-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release of v1.1 Changes: - lazy connection to ssh - fork tview and modify textview to keep only 300kb of data in the buffer - WIP for docker logs
- Loading branch information
Showing
16 changed files
with
385 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package docker | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"io" | ||
"log" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/docker/docker/api/types" | ||
"github.com/docker/docker/client" | ||
) | ||
|
||
// DockerReader reads docker containers' logs. | ||
// It implements the FileReader interface. | ||
type DockerReader struct { | ||
|
||
// docker client | ||
client *client.Client | ||
|
||
// id of the container which logs are read | ||
containerId string | ||
} | ||
|
||
func NewDockerLogReader(host, version string) (*DockerReader, error) { | ||
var defaultTtransport http.RoundTripper = &http.Transport{Proxy: nil} | ||
c := &http.Client{Transport: defaultTtransport} | ||
|
||
if host == "" { | ||
host = client.DefaultDockerHost | ||
} | ||
|
||
if version == "" { | ||
version = client.DefaultVersion | ||
} | ||
|
||
cli, err := client.NewClient(host, version, c, nil) | ||
if err != nil { | ||
return &DockerReader{}, err | ||
} | ||
|
||
return &DockerReader{client: cli}, nil | ||
} | ||
|
||
// Clone returns a clone of DockerReader. | ||
func (d *DockerReader) Clone() *DockerReader { | ||
var clone = DockerReader{client: d.client} | ||
return &clone | ||
} | ||
|
||
//ListContainers is a wrapper around ContainerList with timeout context of 5 seconds. | ||
func (d *DockerReader) ListContainers() ([]types.Container, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
defer cancel() | ||
|
||
return d.client.ContainerList(ctx, types.ContainerListOptions{}) | ||
} | ||
|
||
// Reads the logs from containerId and return an array of bytes, number of bytes read and error if any. | ||
func containerLogs(client *client.Client, containerId string) ([]byte, int64, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
defer cancel() | ||
|
||
reader, err := client.ContainerLogs(ctx, "container_id", types.ContainerLogsOptions{}) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
buf := &bytes.Buffer{} | ||
n, err := io.Copy(buf, reader) | ||
if err != nil && err != io.EOF { | ||
return []byte{}, n, err | ||
} | ||
|
||
return buf.Bytes(), n, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package log | ||
|
||
// Docker represents a docker client. | ||
type Docker interface { | ||
|
||
// ContainerLogs returns the log of the container as []byte, the size of log. | ||
ContainerLogs(containerId string) ([]byte, int32, error, error) | ||
} | ||
|
||
// BytesReader provides an implementation of FileReader interface. | ||
// It works with array of bytes returned by the docker client. | ||
// Due to the fact that we don't know the size of the log before we read it, the behaviour is different then | ||
// RemoteReader. The data is fetched in the FetchSize method and the size of the log is returned. | ||
// Also, we have to keep the difference between the last received data and the actual data. This differece will be return when | ||
// ReadNextChunk is called. | ||
type BytesReader struct { | ||
|
||
// container id | ||
id string | ||
|
||
// Implementation of Docker interface | ||
client Docker | ||
|
||
// holds the last data read from container | ||
data []byte | ||
|
||
// offset represents the last read position | ||
offset int32 | ||
|
||
// total bytes read so far | ||
size int32 | ||
} | ||
|
||
// NewBytesReader creates a new BytesReader. | ||
func NewBytesReader(id string, client Docker) *BytesReader { | ||
return &BytesReader{id, client, []byte(nil), 0, 0} | ||
} | ||
|
||
// GetSize return the number of bytes read. | ||
func (b *BytesReader) GetSize() int32 { | ||
return b.offset | ||
} | ||
|
||
// SetSize sets the size. | ||
// DEPRECATED | ||
func (b *BytesReader) SetSize(size int32) { | ||
// DEPRECATED | ||
} | ||
|
||
// HasNextChunk returns true if the size of data is greater than the offset. | ||
func (b *BytesReader) HasNextChunk() bool { | ||
return b.offset < b.size | ||
} | ||
|
||
// Rewind set the offset to 0. | ||
func (b *BytesReader) Rewind() { | ||
b.offset = 0 | ||
} | ||
|
||
// ReadNextChunk return the part of data from offset to the end of bytes array. | ||
// It return always nil errors because the data was already fetched from container. | ||
func (b *BytesReader) ReadNextChunk() ([]byte, error, error) { | ||
if b.size == b.offset { | ||
return []byte{}, nil, nil | ||
} | ||
|
||
b.offset = b.size | ||
return b.data, nil, nil | ||
} | ||
|
||
// FetchSize read the log from the container and save the any data beyond offset to data field. | ||
// Returns the size of fetched data and container error or connection error. | ||
func (b *BytesReader) FetchSize() (int32, error, error) { | ||
data, n, containerErr, connErr := b.client.ContainerLogs(b.id) | ||
if containerErr != nil || connErr != nil { | ||
return 0, containerErr, connErr | ||
} | ||
|
||
if n < b.offset { | ||
b.Rewind() | ||
} | ||
if n > b.offset { | ||
//remove the previous data and keep only the difference between the last received data and the present data. | ||
b.data = nil | ||
b.data = append(b.data, data[b.offset:]...) | ||
b.size = n | ||
} | ||
return n, nil, nil | ||
} | ||
|
||
func Close() { | ||
// TO NOTHING | ||
} |
Oops, something went wrong.