events

package
v3.1.15+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 21, 2020 License: Apache-2.0 Imports: 31 Imported by: 347

Documentation

Overview

Package events implements the audit log interface events.IAuditLog using filesystem backend.

Audit logs ----------

Audit logs are events associated with user logins, server access and session log events like session.start.

Example audit log event:

{"addr.local":"172.10.1.20:3022",

 "addr.remote":"172.10.1.254:58866",
 "event":"session.start",
 "login":"root",
 "user":"klizhentas@gmail.com"
}

Session Logs ------------

Session logs are a series of events and recorded SSH interactive session playback.

Example session log event:

{
  "time":"2018-01-04T02:12:40.245Z",
  "event":"print",
  "bytes":936,
  "ms":40962,
  "offset":16842,
  "ei":31,
  "ci":29
}

Print event fields ------------------

Print event specifies session output - PTY io recorded by Teleport node or Proxy based on the configuration.

* "offset" is an offset in bytes from a start of a session * "ms" is a delay in milliseconds from the last event occurred * "ci" is a chunk index ordering only print events * "ei" is an event index ordering events from the first one

As in example of print event above, "ei" - is a session event index - 31, while "ci" is a chunk index - meaning that this event is 29th in a row of print events.

Client streaming session logs ------------------------------

Session related logs are delivered in order defined by clients. Every event is ordered and has a session-local index, every next event has index incremented.

Client delivers session events in batches, where every event in the batch is guaranteed to be in continuous order (e.g. no cases with events delivered in a single batch to have missing event or chunk index).

Disk File format ----------------

On disk file format is designed to be compatible with NFS filesystems and provides guarantee that only one auth server writes to the file at a time.

Main Audit Log Format =====================

The main log files are saved as:

/var/lib/teleport/log/<auth-server-id>/<date>.log

The log file is rotated every 24 hours. The old files must be cleaned up or archived by an external tool.

Log file format: utc_date,action,json_fields

Common JSON fields - user : teleport user - login : server OS login, the user logged in as - addr.local : server address:port - addr.remote: connected client's address:port - sid : session ID (GUID format)

Examples: 2016-04-25 22:37:29 +0000 UTC,session.start,{"addr.local":"127.0.0.1:3022","addr.remote":"127.0.0.1:35732","login":"root","sid":"4a9d97de-0b36-11e6-a0b3-d8cb8ae5080e","user":"vincent"} 2016-04-25 22:54:31 +0000 UTC,exec,{"addr.local":"127.0.0.1:3022","addr.remote":"127.0.0.1:35949","command":"-bash -c ls /","login":"root","user":"vincent"}

Session log file format =======================

Each session has its own session log stored as several files:

Index file contains a list of event files and chunks files associated with a session:

/var/lib/teleport/log/sessions/<auth-server-id>/<session-id>.index

The format of the index file contains of two or more lines with pointers to other files:

{"file_name":"<session-id>-<first-event-in-file-index>.events","type":"events","index":<first-event-in-file-index>} {"file_name":"<session-id>-<first-chunk-in-file-offset>.chunks","type":"chunks","offset":<first-chunk-in-file-offset>}

Files:

/var/lib/teleport/log/<auth-server-id>/<session-id>-<first-event-in-file-index>.events
/var/lib/teleport/log/<auth-server-id>/<session-id>-<first-chunk-in-file-offset>.chunks

Where:

  • .events (same events as in the main log, but related to the session)
  • .chunks (recorded session bytes: PTY IO)

Examples ~~~~~~~~

**Single auth server**

In the simplest case, single auth server a1 log for a single session id s1 will consist of three files:

/var/lib/teleport/a1/s1.index

With contents:

{"file_name":"s1-0.events","type":"events","index":0} {"file_name":"s1-0.chunks","type":"chunks","offset":0}

This means that all session events are located in s1-0.events file starting from the first event with index 0 and all chunks are located in file s1-0.chunks file with the byte offset from the start - 0.

File with session events /var/lib/teleport/a1/s1-0.events will contain:

{"ei":0,"event":"session.start", ...} {"ei":1,"event":"resize",...} {"ei":2,"ci":0, "event":"print","bytes":40,"offset":0} {"ei":3,"event":"session.end", ...}

File with recorded session /var/lib/teleport/a1/s1-0.chunks will contain 40 bytes emitted by print event with chunk index 0

**Multiple Auth Servers**

In high availability mode scenario, multiple auth servers will be

deployed behind a load balancer.

Any auth server can go down during session and clients will retry the delivery to the other auth server.

Both auth servers have mounted /var/lib/teleport/log as a shared NFS folder.

To make sure that only one auth server writes to a file at a time, each auth server writes to it's own file in a sub folder named with host UUID of the server.

Client sends the chunks of events related to the session s1 in order, but load balancer sends first batch of event to the first server a1, and the second batch of event to the second server a2.

Server a1 will produce the following file:

/var/lib/teleport/a1/s1.index

With contents:

{"file_name":"s1-0.events","type":"events","index":0} {"file_name":"s1-0.chunks","type":"chunks","offset":0}

Events file /var/lib/teleport/a1/s1-0.events will contain:

{"ei":0,"event":"session.start", ...} {"ei":1,"event":"resize",...} {"ei":2,"ci":0, "event":"print","bytes":40,"offset":0}

Events file /var/lib/teleport/a1/s1-0.chunks will contain 40 bytes emitted by print event with chunk index.

Server a2 will produce the following file:

/var/lib/teleport/a2/s1.index

With contents:

{"file_name":"s1-3.events","type":"events","index":3} {"file_name":"s1-40.chunks","type":"chunks","offset":40}

Events file /var/lib/teleport/a2/s1-4.events will contain:

{"ei":3,"ci":1, "event":"print","bytes":15,"ms":713,"offset":40} {"ei":4,"event":"session.end", ...}

Events file /var/lib/teleport/a2/s1-40.chunks will contain 15 bytes emitted by print event with chunk index 1 and comes after delay of 713 milliseconds.

Offset 40 indicates that the first chunk stored in the file s1-40.chunks comes at an offset of 40 bytes from the start of the session.

Log Search and Playback -----------------------

Log search and playback is aware of multiple auth servers, merges indexes, event streams stored on multiple auth servers.

Index

Constants

View Source
const (
	// EventType is event type/kind
	EventType = "event"
	// EventID is a unique event identifier
	EventID = "uid"
	// EventTime is event time
	EventTime = "time"
	// EventLogin is OS login
	EventLogin = "login"
	// EventUser is teleport user name
	EventUser = "user"
	// EventProtocol specifies protocol that was captured
	EventProtocol = "proto"
	// EventProtocolsSSH specifies SSH as a type of captured protocol
	EventProtocolSSH = "ssh"
	// EventProtocolKube specifies kubernetes as a type of captured protocol
	EventProtocolKube = "kube"
	// LocalAddr is a target address on the host
	LocalAddr = "addr.local"
	// RemoteAddr is a client (user's) address
	RemoteAddr = "addr.remote"
	// EventCursor is an event ID (used as cursor value for enumeration, not stored)
	EventCursor = "id"

	// EventIndex is an event index as received from the logging server
	EventIndex = "ei"

	// EventNamespace is a namespace of the session event
	EventNamespace = "namespace"

	// SessionPrintEvent event happens every time a write occurs to
	// temirnal I/O during a session
	SessionPrintEvent = "print"

	// SessionPrintEventBytes says how many bytes have been written into the session
	// during "print" event
	SessionPrintEventBytes = "bytes"

	// SessionEventTimestamp is an offset (in milliseconds) since the beginning of the
	// session when the terminal IO event happened
	SessionEventTimestamp = "ms"

	// SessionEvent indicates that session has been initiated
	// or updated by a joining party on the server
	SessionStartEvent = "session.start"

	// SessionEndEvent indicates that a session has ended
	SessionEndEvent = "session.end"
	// SessionUploadEvent indicates that session has been uploaded to the external storage
	SessionUploadEvent = "session.upload"
	// URL is used for a session upload URL
	URL = "url"

	SessionEventID  = "sid"
	SessionServerID = "server_id"

	// SessionByteOffset is the number of bytes written to session stream since
	// the beginning
	SessionByteOffset = "offset"

	// SessionJoinEvent indicates that someone joined a session
	SessionJoinEvent = "session.join"
	// SessionLeaveEvent indicates that someone left a session
	SessionLeaveEvent = "session.leave"

	// ClientDisconnectEvent is emitted when client is disconnected
	// by the server due to inactivity or any other reason
	ClientDisconnectEvent = "client.disconnect"

	// Reason is a field that specifies reason for event, e.g. in disconnect
	// event it explains why server disconnected the client
	Reason = "reason"

	// UserLoginEvent indicates that a user logged into web UI or via tsh
	UserLoginEvent = "user.login"
	// LoginMethod is the event field indicating how the login was performed
	LoginMethod = "method"
	// LoginMethodLocal represents login with username/password
	LoginMethodLocal = "local"
	// LoginMethodOIDC represents login with OIDC
	LoginMethodOIDC = "oidc"
	// LoginMethodSAML represents login with SAML
	LoginMethodSAML = "saml"
	// LoginMethodGithub represents login with Github
	LoginMethodGithub = "github"

	// ExecEvent is an exec command executed by script or user on
	// the server side
	ExecEvent        = "exec"
	ExecEventCommand = "command"
	ExecEventCode    = "exitCode"
	ExecEventError   = "exitError"

	// SubsystemEvent is the result of the execution of a subsystem.
	SubsystemEvent = "subsystem"
	SubsystemName  = "name"
	SubsystemError = "exitError"

	// Port forwarding event
	PortForwardEvent   = "port"
	PortForwardAddr    = "addr"
	PortForwardSuccess = "success"
	PortForwardErr     = "error"

	// AuthAttemptEvent is authentication attempt that either
	// succeeded or failed based on event status
	AuthAttemptEvent   = "auth"
	AuthAttemptSuccess = "success"
	AuthAttemptErr     = "error"
	AuthAttemptMessage = "message"

	// SCPEvent means data transfer that occurred on the server
	SCPEvent    = "scp"
	SCPPath     = "path"
	SCPLengh    = "len"
	SCPAction   = "action"
	SCPUpload   = "upload"
	SCPDownload = "download"

	// ResizeEvent means that some user resized PTY on the client
	ResizeEvent  = "resize"
	TerminalSize = "size" // expressed as 'W:H'
)
View Source
const (
	// V1 is the V1 version of slice chunks API,
	// it is 0 because it was not defined before
	V1 = 0
	// V2 is the V2 version of slice chunks  API
	V2 = 2
	// V3 is almost like V2, but it assumes
	// that session recordings are being uploaded
	// at the end of the session, so it skips writing session event index
	// on the fly
	V3 = 3
)
View Source
const (
	// SessionLogsDir is a subdirectory inside the eventlog data dir
	// where all session-specific logs and streams are stored, like
	// in /var/lib/teleport/logs/sessions
	SessionLogsDir = "sessions"

	// PlaybacksDir is a directory for playbacks
	PlaybackDir = "playbacks"

	// LogfileExt defines the ending of the daily event log file
	LogfileExt = ".log"

	// SymlinkFilename is a name of the symlink pointing to the last
	// current log file
	SymlinkFilename = "events.log"
)
View Source
const (
	// MaxChunkBytes defines the maximum size of a session stream chunk that
	// can be requested via AuditLog.GetSessionChunk(). Set to 5MB
	MaxChunkBytes = 1024 * 1024 * 5
)

Variables

View Source
var (
	ErrInvalidLengthSlice = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowSlice   = fmt.Errorf("proto: integer overflow")
)

Functions

func NewSessionArchive

func NewSessionArchive(dataDir, serverID, namespace string, sessionID session.ID) (io.ReadCloser, error)

NewSessionArchive returns generated tar archive with all components

func RegisterAuditLogServer

func RegisterAuditLogServer(s *grpc.Server, srv AuditLogServer)

func ValidateArchive

func ValidateArchive(reader io.Reader, serverID string) error

ValidateArchive validates namespace and serverID fields within all events in the archive.

func ValidateEvent

func ValidateEvent(f EventFields, serverID string) error

ValidateEvent checks the the fields within an event match the passed in expected values.

Types

type AuditLog added in v1.0.0

type AuditLog struct {
	sync.Mutex
	*log.Entry
	AuditLogConfig
	// contains filtered or unexported fields
}

AuditLog is a new combined facility to record Teleport events and sessions. It implements IAuditLog

func NewAuditLog added in v1.0.0

func NewAuditLog(cfg AuditLogConfig) (*AuditLog, error)

Creates and returns a new Audit Log object whish will store its logfiles in a given directory. Session recording can be disabled by setting recordSessions to false.

func (*AuditLog) Close added in v1.0.0

func (l *AuditLog) Close() error

Closes the audit log, which inluces closing all file handles and releasing all session loggers

func (*AuditLog) EmitAuditEvent added in v1.0.0

func (l *AuditLog) EmitAuditEvent(eventType string, fields EventFields) error

EmitAuditEvent adds a new event to the log. Part of auth.IAuditLog interface.

func (*AuditLog) GetSessionChunk added in v1.0.0

func (l *AuditLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)

GetSessionChunk returns a reader which console and web clients request to receive a live stream of a given session. The reader allows access to a session stream range from offsetBytes to offsetBytes+maxBytes

func (*AuditLog) GetSessionEvents added in v1.0.0

func (l *AuditLog) GetSessionEvents(namespace string, sid session.ID, afterN int, includePrintEvents bool) ([]EventFields, error)

Returns all events that happen during a session sorted by time (oldest first).

Can be filtered by 'after' (cursor value to return events newer than)

This function is usually used in conjunction with GetSessionReader to replay recorded session streams.

func (*AuditLog) PostSessionSlice

func (l *AuditLog) PostSessionSlice(slice SessionSlice) error

PostSessionSlice submits slice of session chunks to the audit log server.

func (*AuditLog) SearchEvents added in v1.0.0

func (l *AuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)

SearchEvents finds events. Results show up sorted by date (newest first), limit is used when set to value > 0

func (*AuditLog) SearchSessionEvents

func (l *AuditLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) ([]EventFields, error)

SearchSessionEvents searches for session related events. Used to find completed sessions.

func (*AuditLog) UploadSessionRecording

func (l *AuditLog) UploadSessionRecording(r SessionRecording) error

UploadSessionRecording persists the session recording locally or to third party storage.

func (*AuditLog) WaitForDelivery

func (l *AuditLog) WaitForDelivery(context.Context) error

type AuditLogClient

type AuditLogClient interface {
	SubmitSessionSlice(ctx context.Context, opts ...grpc.CallOption) (AuditLog_SubmitSessionSliceClient, error)
}

func NewAuditLogClient

func NewAuditLogClient(cc *grpc.ClientConn) AuditLogClient

type AuditLogConfig

type AuditLogConfig struct {
	// DataDir is the directory where audit log stores the data
	DataDir string

	// ServerID is the id of the audit log server
	ServerID string

	// RecordSessions controls if sessions are recorded along with audit events.
	RecordSessions bool

	// RotationPeriod defines how frequently to rotate the log file
	RotationPeriod time.Duration

	// SessionIdlePeriod defines the period after which sessions will be considered
	// idle (and audit log will free up some resources)
	SessionIdlePeriod time.Duration

	// Clock is a clock either real one or used in tests
	Clock clockwork.Clock

	// UIDGenerator is used to generate unique IDs for events
	UIDGenerator utils.UID

	// GID if provided will be used to set group ownership of the directory
	// to GID
	GID *int

	// UID if provided will be used to set userownership of the directory
	// to UID
	UID *int

	// DirMask if provided will be used to set directory mask access
	// otherwise set to default value
	DirMask *os.FileMode

	// PlaybackRecycleTTL is a time after uncompressed playback files will be
	// deleted
	PlaybackRecycleTTL time.Duration

	// UploadHandler is a pluggable external upload handler,
	// used to fetch sessions from external sources
	UploadHandler UploadHandler

	// ExternalLog is a pluggable external log service
	ExternalLog IAuditLog

	// EventC is evnets channel for testing purposes, not used if empty
	EventsC chan *AuditLogEvent
}

AuditLogConfig specifies configuration for AuditLog server

func (*AuditLogConfig) CheckAndSetDefaults

func (a *AuditLogConfig) CheckAndSetDefaults() error

CheckAndSetDefaults checks and sets defaults

type AuditLogEvent

type AuditLogEvent struct {
	// Type is an event type
	Type string
	// Error is an event error
	Error error
}

AuditLogEvent is an internal audit log event

type AuditLogServer

type AuditLogServer interface {
	SubmitSessionSlice(AuditLog_SubmitSessionSliceServer) error
}

type AuditLog_SubmitSessionSliceClient

type AuditLog_SubmitSessionSliceClient interface {
	Send(*SessionSlice) error
	CloseAndRecv() (*empty.Empty, error)
	grpc.ClientStream
}

type AuditLog_SubmitSessionSliceServer

type AuditLog_SubmitSessionSliceServer interface {
	SendAndClose(*empty.Empty) error
	Recv() (*SessionSlice, error)
	grpc.ServerStream
}

type ByTimeAndIndex

type ByTimeAndIndex []EventFields

ByTimeAndIndex sorts events by time extracting timestamp from JSON field and if there are several session events with the same session by event index, regardless of the time

func (ByTimeAndIndex) Len

func (f ByTimeAndIndex) Len() int

func (ByTimeAndIndex) Less

func (f ByTimeAndIndex) Less(i, j int) bool

func (ByTimeAndIndex) Swap

func (f ByTimeAndIndex) Swap(i, j int)

type DiscardAuditLog added in v1.1.0

type DiscardAuditLog struct{}

DiscardAuditLog is do-nothing, discard-everything implementation of IAuditLog interface used for cases when audit is turned off

func NewDiscardAuditLog

func NewDiscardAuditLog() *DiscardAuditLog

NewDiscardAuditLog returns a no-op audit log instance

func (*DiscardAuditLog) Close

func (d *DiscardAuditLog) Close() error

func (*DiscardAuditLog) EmitAuditEvent added in v1.1.0

func (d *DiscardAuditLog) EmitAuditEvent(eventType string, fields EventFields) error

func (*DiscardAuditLog) GetSessionChunk added in v1.1.0

func (d *DiscardAuditLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)

func (*DiscardAuditLog) GetSessionEvents added in v1.1.0

func (d *DiscardAuditLog) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)

func (*DiscardAuditLog) PostSessionSlice

func (d *DiscardAuditLog) PostSessionSlice(SessionSlice) error

func (*DiscardAuditLog) SearchEvents added in v1.1.0

func (d *DiscardAuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)

func (*DiscardAuditLog) SearchSessionEvents

func (d *DiscardAuditLog) SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error)

func (*DiscardAuditLog) UploadSessionRecording

func (d *DiscardAuditLog) UploadSessionRecording(SessionRecording) error

func (*DiscardAuditLog) WaitForDelivery

func (d *DiscardAuditLog) WaitForDelivery(context.Context) error

type DiscardRecorder

type DiscardRecorder struct {
	DiscardAuditLog
}

DiscardRecorder discards all writes

func (*DiscardRecorder) Close

func (*DiscardRecorder) Close() error

Close does nothing and always succeeds

func (*DiscardRecorder) GetAuditLog

func (d *DiscardRecorder) GetAuditLog() IAuditLog

GetAuditLog returns audit log associated with this recorder

func (*DiscardRecorder) Write

func (*DiscardRecorder) Write(b []byte) (int, error)

Write acks all writes but discards them

type DiskSessionLogger

type DiskSessionLogger struct {
	DiskSessionLoggerConfig

	*log.Entry

	sync.Mutex
	// contains filtered or unexported fields
}

DiskSessionLogger implements a disk based session logger. The imporant property of the disk based logger is that it never fails and can be used as a fallback implementation behind more sophisticated loggers.

func NewDiskSessionLogger

func NewDiskSessionLogger(cfg DiskSessionLoggerConfig) (*DiskSessionLogger, error)

NewDiskSessionLogger creates new disk based session logger

func (*DiskSessionLogger) Close

func (sl *DiskSessionLogger) Close() error

Close is called when clients close on the requested "session writer". We ignore their requests because this writer (file) should be closed only when the session logger is closed

func (*DiskSessionLogger) Finalize

func (sl *DiskSessionLogger) Finalize() error

Finalize is called by the session when it's closing. This is where we're releasing audit resources associated with the session

func (*DiskSessionLogger) LogEvent

func (sl *DiskSessionLogger) LogEvent(fields EventFields) error

LogEvent logs an event associated with this session

func (*DiskSessionLogger) PostSessionSlice

func (sl *DiskSessionLogger) PostSessionSlice(slice SessionSlice) error

PostSessionSlice takes series of events associated with the session and writes them to events files and data file for future replays

type DiskSessionLoggerConfig

type DiskSessionLoggerConfig struct {
	// SessionID is the session id of the logger
	SessionID session.ID
	// DataDir is data directory for session events files
	DataDir string
	// Clock is the clock replacement
	Clock clockwork.Clock
	// RecordSessions controls if sessions are recorded along with audit events.
	RecordSessions bool
	// Namespace is logger namespace
	Namespace string
	// ServerID is a server ID
	ServerID string
}

DiskSessionLoggerConfig sets up parameters for disk session logger associated with the session ID

func (*DiskSessionLoggerConfig) CheckAndSetDefaults

func (cfg *DiskSessionLoggerConfig) CheckAndSetDefaults() error

type EventFields added in v1.0.0

type EventFields map[string]interface{}

EventFields instance is attached to every logged event

func EventFromChunk

func EventFromChunk(sessionID string, chunk *SessionChunk) (EventFields, error)

EventFromChunk returns event converted from session chunk

func (EventFields) AsString added in v1.0.0

func (f EventFields) AsString() string

String returns a string representation of an event structure

func (EventFields) GetID

func (f EventFields) GetID() string

GetID returns the unique event ID

func (EventFields) GetInt added in v1.0.0

func (f EventFields) GetInt(key string) int

GetString returns an int representation of a logged field

func (EventFields) GetString added in v1.0.0

func (f EventFields) GetString(key string) string

GetString returns a string representation of a logged field

func (EventFields) GetTime added in v1.0.0

func (f EventFields) GetTime(key string) time.Time

GetString returns an int representation of a logged field

func (EventFields) GetType added in v1.0.0

func (f EventFields) GetType() string

GetType returns the type (string) of the event

func (EventFields) HasField

func (f EventFields) HasField(key string) bool

HasField returns true if the field exists in the event.

type FileLog

type FileLog struct {
	*log.Entry
	FileLogConfig
	sync.Mutex
	// contains filtered or unexported fields
}

FileLog is a file local audit events log, logs all events to the local file in json encoded form

func NewFileLog

func NewFileLog(cfg FileLogConfig) (*FileLog, error)

NewFileLog returns a new instance of a file log

func (*FileLog) Close

func (l *FileLog) Close() error

Close closes the audit log, which inluces closing all file handles and releasing all session loggers

func (*FileLog) EmitAuditEvent

func (l *FileLog) EmitAuditEvent(eventType string, fields EventFields) error

EmitAuditEvent adds a new event to the log. Part of auth.IFileLog interface.

func (*FileLog) GetSessionChunk

func (l *FileLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)

func (*FileLog) GetSessionEvents

func (l *FileLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) ([]EventFields, error)

func (*FileLog) PostSessionSlice

func (l *FileLog) PostSessionSlice(slice SessionSlice) error

func (*FileLog) SearchEvents

func (l *FileLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)

SearchEvents finds events. Results show up sorted by date (newest first), limit is used when set to value > 0

func (*FileLog) SearchSessionEvents

func (l *FileLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) ([]EventFields, error)

SearchSessionEvents searches for session related events. Used to find completed sessions.

func (*FileLog) UploadSessionRecording

func (l *FileLog) UploadSessionRecording(SessionRecording) error

func (*FileLog) WaitForDelivery

func (l *FileLog) WaitForDelivery(context.Context) error

type FileLogConfig

type FileLogConfig struct {
	// RotationPeriod defines how frequently to rotate the log file
	RotationPeriod time.Duration
	// Dir is a directory where logger puts the files
	Dir string
	// SymlinkDir is a directory for symlink pointer to the current log
	SymlinkDir string
	// Clock is a clock interface, used in tests
	Clock clockwork.Clock
	// UIDGenerator is used to generate unique IDs for events
	UIDGenerator utils.UID
	// SearchDirs is a function that returns
	// search directories, if not set, only Dir is used
	SearchDirs func() ([]string, error)
}

FileLogConfig is a configuration for file log

func (*FileLogConfig) CheckAndSetDefaults

func (cfg *FileLogConfig) CheckAndSetDefaults() error

CheckAndSetDefaults checks and sets config defaults

type ForwardRecorder

type ForwardRecorder struct {
	// ForwardRecorderConfig specifies session recorder configuration
	ForwardRecorderConfig

	// Entry holds the structured logger
	*logrus.Entry

	// AuditLog is the audit log to store session chunks
	AuditLog IAuditLog
}

ForwardRecorder implements io.Writer to be plugged into the multi-writer associated with every session. It forwards session stream to the audit log

func NewForwardRecorder

func NewForwardRecorder(cfg ForwardRecorderConfig) (*ForwardRecorder, error)

NewForwardRecorder returns a new instance of session recorder

func (*ForwardRecorder) Close

func (r *ForwardRecorder) Close() error

Close closes audit log session recorder

func (*ForwardRecorder) GetAuditLog

func (r *ForwardRecorder) GetAuditLog() IAuditLog

GetAuditLog returns audit log associated with this recorder

func (*ForwardRecorder) Write

func (r *ForwardRecorder) Write(data []byte) (int, error)

Write takes a chunk and writes it into the audit log

type ForwardRecorderConfig

type ForwardRecorderConfig struct {
	// DataDir is a data directory to record
	DataDir string

	// SessionID defines the session to record.
	SessionID session.ID

	// Namespace is the session namespace.
	Namespace string

	// RecordSessions stores info on whether to record sessions
	RecordSessions bool

	// Component is a component used for logging
	Component string

	// ForwardTo is external audit log where events will be forwarded
	ForwardTo IAuditLog
}

ForwardRecorderConfig specifies config for session recording

func (*ForwardRecorderConfig) CheckAndSetDefaults

func (cfg *ForwardRecorderConfig) CheckAndSetDefaults() error

type Forwarder

type Forwarder struct {
	ForwarderConfig

	sync.Mutex
	// contains filtered or unexported fields
}

ForwarderConfig forwards session log events to the auth server, and writes the session playback to disk

func NewForwarder

func NewForwarder(cfg ForwarderConfig) (*Forwarder, error)

NewForwarder returns a new instance of session forwarder

func (*Forwarder) Close

func (l *Forwarder) Close() error

Closer releases connection and resources associated with log if any

func (*Forwarder) EmitAuditEvent

func (l *Forwarder) EmitAuditEvent(eventType string, fields EventFields) error

EmitAuditEvent emits audit event

func (*Forwarder) GetSessionChunk

func (l *Forwarder) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)

GetSessionChunk returns a reader which can be used to read a byte stream of a recorded session starting from 'offsetBytes' (pass 0 to start from the beginning) up to maxBytes bytes.

If maxBytes > MaxChunkBytes, it gets rounded down to MaxChunkBytes

func (*Forwarder) GetSessionEvents

func (l *Forwarder) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)

Returns all events that happen during a session sorted by time (oldest first).

after tells to use only return events after a specified cursor Id

This function is usually used in conjunction with GetSessionReader to replay recorded session streams.

func (*Forwarder) PostSessionSlice

func (l *Forwarder) PostSessionSlice(slice SessionSlice) error

PostSessionSlice sends chunks of recorded session to the event log

func (*Forwarder) SearchEvents

func (l *Forwarder) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)

SearchEvents is a flexible way to find The format of a query string depends on the implementing backend. A recommended format is urlencoded (good enough for Lucene/Solr)

Pagination is also defined via backend-specific query format.

The only mandatory requirement is a date range (UTC). Results must always show up sorted by date (newest first)

func (*Forwarder) SearchSessionEvents

func (l *Forwarder) SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error)

SearchSessionEvents returns session related events only. This is used to find completed session.

func (*Forwarder) UploadSessionRecording

func (l *Forwarder) UploadSessionRecording(r SessionRecording) error

UploadSessionRecording uploads session recording to the audit server

func (*Forwarder) WaitForDelivery

func (l *Forwarder) WaitForDelivery(ctx context.Context) error

WaitForDelivery waits for resources to be released and outstanding requests to complete after calling Close method

type ForwarderConfig

type ForwarderConfig struct {
	// SessionID is a session id to write
	SessionID session.ID
	// ServerID is a serverID data directory
	ServerID string
	// DataDir is a data directory
	DataDir string
	// RecordSessions is a sessions recording setting
	RecordSessions bool
	// Namespace is a namespace of the session
	Namespace string
	// ForwardTo is the audit log to forward non-print events to
	ForwardTo IAuditLog
	// Clock is a clock to set for tests
	Clock clockwork.Clock
}

ForwarderConfig forwards session log events to the auth server, and writes the session playback to disk

func (*ForwarderConfig) CheckAndSetDefaults

func (s *ForwarderConfig) CheckAndSetDefaults() error

CheckAndSetDefaults checks and sets default values

type IAuditLog added in v1.0.0

type IAuditLog interface {
	// Closer releases connection and resources associated with log if any
	io.Closer

	// EmitAuditEvent emits audit event
	EmitAuditEvent(eventType string, fields EventFields) error

	// DELETE IN: 2.7.0
	// This method is no longer necessary as nodes and proxies >= 2.7.0
	// use UploadSessionRecording method.
	// PostSessionSlice sends chunks of recorded session to the event log
	PostSessionSlice(SessionSlice) error

	// UploadSessionRecording uploads session recording to the audit server
	UploadSessionRecording(r SessionRecording) error

	// GetSessionChunk returns a reader which can be used to read a byte stream
	// of a recorded session starting from 'offsetBytes' (pass 0 to start from the
	// beginning) up to maxBytes bytes.
	//
	// If maxBytes > MaxChunkBytes, it gets rounded down to MaxChunkBytes
	GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)

	// Returns all events that happen during a session sorted by time
	// (oldest first).
	//
	// after tells to use only return events after a specified cursor Id
	//
	// This function is usually used in conjunction with GetSessionReader to
	// replay recorded session streams.
	GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)

	// SearchEvents is a flexible way to find events. The format of a query string
	// depends on the implementing backend. A recommended format is urlencoded
	// (good enough for Lucene/Solr)
	//
	// Pagination is also defined via backend-specific query format.
	//
	// The only mandatory requirement is a date range (UTC). Results must always
	// show up sorted by date (newest first)
	SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)

	// SearchSessionEvents returns session related events only. This is used to
	// find completed session.
	SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error)

	// WaitForDelivery waits for resources to be released and outstanding requests to
	// complete after calling Close method
	WaitForDelivery(context.Context) error
}

IAuditLog is the primary (and the only external-facing) interface for AuditLogger. If you wish to implement a different kind of logger (not filesystem-based), you have to implement this interface

type MockAuditLog

type MockAuditLog struct {
	sync.Mutex

	FailedAttemptsC chan *SessionSlice
	SlicesC         chan *SessionSlice
	// contains filtered or unexported fields
}

MockAuditLog is audit log used for tests

func NewMockAuditLog

func NewMockAuditLog(capacity int) *MockAuditLog

func (*MockAuditLog) Close

func (d *MockAuditLog) Close() error

func (*MockAuditLog) EmitAuditEvent

func (d *MockAuditLog) EmitAuditEvent(eventType string, fields EventFields) error

func (*MockAuditLog) GetError

func (d *MockAuditLog) GetError() error

func (*MockAuditLog) GetSessionChunk

func (d *MockAuditLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)

func (*MockAuditLog) GetSessionEvents

func (d *MockAuditLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) ([]EventFields, error)

func (*MockAuditLog) PostSessionSlice

func (d *MockAuditLog) PostSessionSlice(slice SessionSlice) error

func (*MockAuditLog) SearchEvents

func (d *MockAuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)

func (*MockAuditLog) SearchSessionEvents

func (d *MockAuditLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) ([]EventFields, error)

func (*MockAuditLog) SetError

func (d *MockAuditLog) SetError(e error)

func (*MockAuditLog) UploadSessionRecording

func (d *MockAuditLog) UploadSessionRecording(SessionRecording) error

func (*MockAuditLog) WaitForDelivery

func (d *MockAuditLog) WaitForDelivery(context.Context) error

type MultiLog

type MultiLog struct {
	// contains filtered or unexported fields
}

MultiLog is a logger that fan outs write operations to all loggers, and performs all read and search operations on the first logger that implements the operation

func NewMultiLog

func NewMultiLog(loggers ...IAuditLog) *MultiLog

NewMultiLog returns a new instance of a multi logger

func (*MultiLog) Close

func (m *MultiLog) Close() error

Closer releases connections and resources associated with logs if any

func (*MultiLog) EmitAuditEvent

func (m *MultiLog) EmitAuditEvent(eventType string, fields EventFields) error

EmitAuditEvent emits audit event

func (*MultiLog) GetSessionChunk

func (m *MultiLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) (data []byte, err error)

GetSessionChunk returns a reader which can be used to read a byte stream of a recorded session starting from 'offsetBytes' (pass 0 to start from the beginning) up to maxBytes bytes.

If maxBytes > MaxChunkBytes, it gets rounded down to MaxChunkBytes

func (*MultiLog) GetSessionEvents

func (m *MultiLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) (events []EventFields, err error)

Returns all events that happen during a session sorted by time (oldest first).

after tells to use only return events after a specified cursor Id

This function is usually used in conjunction with GetSessionReader to replay recorded session streams.

func (*MultiLog) PostSessionSlice

func (m *MultiLog) PostSessionSlice(slice SessionSlice) error

DELETE IN: 2.7.0 This method is no longer necessary as nodes and proxies >= 2.7.0 use UploadSessionRecording method. PostSessionSlice sends chunks of recorded session to the event log

func (*MultiLog) SearchEvents

func (m *MultiLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) (events []EventFields, err error)

SearchEvents is a flexible way to find events. The format of a query string depends on the implementing backend. A recommended format is urlencoded (good enough for Lucene/Solr)

Pagination is also defined via backend-specific query format.

The only mandatory requirement is a date range (UTC). Results must always show up sorted by date (newest first)

func (*MultiLog) SearchSessionEvents

func (m *MultiLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) (events []EventFields, err error)

SearchSessionEvents returns session related events only. This is used to find completed session.

func (*MultiLog) UploadSessionRecording

func (m *MultiLog) UploadSessionRecording(rec SessionRecording) error

UploadSessionRecording uploads session recording to the audit server

func (*MultiLog) WaitForDelivery

func (m *MultiLog) WaitForDelivery(ctx context.Context) error

WaitForDelivery waits for resources to be released and outstanding requests to complete after calling Close method

type SessionChunk

type SessionChunk struct {
	// Time is the occurence of this event
	Time int64 `protobuf:"varint,2,opt,name=Time,json=time,proto3" json:"Time,omitempty"`
	// Data is captured data, contains event fields in case of event, session data otherwise
	Data []byte `protobuf:"bytes,3,opt,name=Data,json=data,proto3" json:"Data,omitempty"`
	// EventType is event type
	EventType string `protobuf:"bytes,4,opt,name=EventType,json=eventType,proto3" json:"EventType,omitempty"`
	// EventIndex is the event global index
	EventIndex int64 `protobuf:"varint,5,opt,name=EventIndex,json=eventIndex,proto3" json:"EventIndex,omitempty"`
	// Index is the autoincremented chunk index
	ChunkIndex int64 `protobuf:"varint,6,opt,name=ChunkIndex,json=chunkIndex,proto3" json:"ChunkIndex,omitempty"`
	// Offset is an offset from the previous chunk in bytes
	Offset int64 `protobuf:"varint,7,opt,name=Offset,json=offset,proto3" json:"Offset,omitempty"`
	// Delay is a delay from the previous event in milliseconds
	Delay                int64    `protobuf:"varint,8,opt,name=Delay,json=delay,proto3" json:"Delay,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

SessionChunk is a chunk to be posted in the context of the session

func (*SessionChunk) Descriptor

func (*SessionChunk) Descriptor() ([]byte, []int)

func (*SessionChunk) GetChunkIndex

func (m *SessionChunk) GetChunkIndex() int64

func (*SessionChunk) GetData

func (m *SessionChunk) GetData() []byte

func (*SessionChunk) GetDelay

func (m *SessionChunk) GetDelay() int64

func (*SessionChunk) GetEventIndex

func (m *SessionChunk) GetEventIndex() int64

func (*SessionChunk) GetEventType

func (m *SessionChunk) GetEventType() string

func (*SessionChunk) GetOffset

func (m *SessionChunk) GetOffset() int64

func (*SessionChunk) GetTime

func (m *SessionChunk) GetTime() int64

func (*SessionChunk) Marshal

func (m *SessionChunk) Marshal() (dAtA []byte, err error)

func (*SessionChunk) MarshalTo

func (m *SessionChunk) MarshalTo(dAtA []byte) (int, error)

func (*SessionChunk) ProtoMessage

func (*SessionChunk) ProtoMessage()

func (*SessionChunk) Reset

func (m *SessionChunk) Reset()

func (*SessionChunk) Size

func (m *SessionChunk) Size() (n int)

func (*SessionChunk) String

func (m *SessionChunk) String() string

func (*SessionChunk) Unmarshal

func (m *SessionChunk) Unmarshal(dAtA []byte) error

func (*SessionChunk) XXX_DiscardUnknown

func (m *SessionChunk) XXX_DiscardUnknown()

func (*SessionChunk) XXX_Marshal

func (m *SessionChunk) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*SessionChunk) XXX_Merge

func (dst *SessionChunk) XXX_Merge(src proto.Message)

func (*SessionChunk) XXX_Size

func (m *SessionChunk) XXX_Size() int

func (*SessionChunk) XXX_Unmarshal

func (m *SessionChunk) XXX_Unmarshal(b []byte) error

type SessionLogger added in v1.0.0

type SessionLogger interface {
	// LogEvent logs events associated with this session.
	LogEvent(fields EventFields) error

	// Close is called when clients close on the requested "session writer".
	// We ignore their requests because this writer (file) should be closed only
	// when the session logger is closed.
	Close() error

	// Finalize is called by the session when it's closing. This is where we're
	// releasing audit resources associated with the session
	Finalize() error

	// PostSessionSlice posts session slice
	PostSessionSlice(slice SessionSlice) error
}

sessionLogger is an interface that all session loggers must implement.

type SessionRecorder

type SessionRecorder interface {
	io.Writer
	io.Closer
	// GetAuditLog returns audit log associated with this log
	GetAuditLog() IAuditLog
}

SessionRecorder implements io.Writer to be plugged into the multi-writer associated with every session. It forwards session stream to the audit log

type SessionRecording

type SessionRecording struct {
	// Namespace is a session namespace
	Namespace string
	// SessionID is a session ID
	SessionID session.ID
	// Recording is a packaged tarball recording
	Recording io.Reader
}

SessionRecording is a recording of a live session

func (*SessionRecording) CheckAndSetDefaults

func (l *SessionRecording) CheckAndSetDefaults() error

CheckAndSetDefaults checks and sets default parameters

type SessionSlice

type SessionSlice struct {
	// Namespace is a session namespace
	Namespace string `protobuf:"bytes,1,opt,name=Namespace,json=namespace,proto3" json:"Namespace,omitempty"`
	// SessionID is a session ID associated with this chunk
	SessionID string `protobuf:"bytes,2,opt,name=SessionID,json=sessionID,proto3" json:"SessionID,omitempty"`
	// Chunks is a list of submitted session chunks
	Chunks []*SessionChunk `protobuf:"bytes,3,rep,name=Chunks,json=chunks" json:"Chunks,omitempty"`
	// Version specifies session slice version
	Version              int64    `protobuf:"varint,4,opt,name=Version,json=version,proto3" json:"Version,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

SessionSlice is a slice of submitted chunks

func (*SessionSlice) Descriptor

func (*SessionSlice) Descriptor() ([]byte, []int)

func (*SessionSlice) GetChunks

func (m *SessionSlice) GetChunks() []*SessionChunk

func (*SessionSlice) GetNamespace

func (m *SessionSlice) GetNamespace() string

func (*SessionSlice) GetSessionID

func (m *SessionSlice) GetSessionID() string

func (*SessionSlice) GetVersion

func (m *SessionSlice) GetVersion() int64

func (*SessionSlice) Marshal

func (m *SessionSlice) Marshal() (dAtA []byte, err error)

func (*SessionSlice) MarshalTo

func (m *SessionSlice) MarshalTo(dAtA []byte) (int, error)

func (*SessionSlice) ProtoMessage

func (*SessionSlice) ProtoMessage()

func (*SessionSlice) Reset

func (m *SessionSlice) Reset()

func (*SessionSlice) Size

func (m *SessionSlice) Size() (n int)

func (*SessionSlice) String

func (m *SessionSlice) String() string

func (*SessionSlice) Unmarshal

func (m *SessionSlice) Unmarshal(dAtA []byte) error

func (*SessionSlice) XXX_DiscardUnknown

func (m *SessionSlice) XXX_DiscardUnknown()

func (*SessionSlice) XXX_Marshal

func (m *SessionSlice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*SessionSlice) XXX_Merge

func (dst *SessionSlice) XXX_Merge(src proto.Message)

func (*SessionSlice) XXX_Size

func (m *SessionSlice) XXX_Size() int

func (*SessionSlice) XXX_Unmarshal

func (m *SessionSlice) XXX_Unmarshal(b []byte) error

type UploadEvent

type UploadEvent struct {
	// SessionID is a session ID
	SessionID string
	// Error is set in case if event resulted in error
	Error error
}

UploadEvent is emitted by uploader and is used in tests

type UploadHandler

type UploadHandler interface {
	// Upload uploads session tarball and returns URL with uploaded file
	// in case of success.
	Upload(ctx context.Context, sessionID session.ID, readCloser io.Reader) (string, error)
	// Download downloads session tarball and writes it to writer
	Download(ctx context.Context, sessionID session.ID, writer io.WriterAt) error
}

UploadHandler is a function supplied by the user, it will upload the file

type Uploader

type Uploader struct {
	UploaderConfig

	*log.Entry
	// contains filtered or unexported fields
}

Uploader implements a disk based session logger. The imporant property of the disk based logger is that it never fails and can be used as a fallback implementation behind more sophisticated loggers.

func NewUploader

func NewUploader(cfg UploaderConfig) (*Uploader, error)

NewUploader creates new disk based session logger

func (*Uploader) Scan

func (u *Uploader) Scan() error

Scan scans the directory and uploads recordings

func (*Uploader) Serve

func (u *Uploader) Serve() error

func (*Uploader) Stop

func (u *Uploader) Stop() error

type UploaderConfig

type UploaderConfig struct {
	// DataDir is data directory for session events files
	DataDir string
	// Clock is the clock replacement
	Clock clockwork.Clock
	// Namespace is logger namespace
	Namespace string
	// ServerID is a server ID
	ServerID string
	// Context is an optional context
	Context context.Context
	// ScanPeriod is a uploader dir scan period
	ScanPeriod time.Duration
	// ConcurrentUploads sets up how many parallel uploads to schedule
	ConcurrentUploads int
	// AuditLog is audit log client
	AuditLog IAuditLog
	// EventsC is an event channel used to signal events
	// used in tests
	EventsC chan *UploadEvent
}

UploaderConfig sets up configuration for uploader service

func (*UploaderConfig) CheckAndSetDefaults

func (cfg *UploaderConfig) CheckAndSetDefaults() error

CheckAndSetDefaults checks and sets default values of UploaderConfig

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL