accesslog

package
v12.2.0-alpha4 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2021 License: BSD-3-Clause Imports: 21 Imported by: 33

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// UTC returns time with UTC based location.
	UTC = clockFunc(func() time.Time { return time.Now().UTC() })
	// TClock accepts a static time.Time to use as
	// accesslog's Now method on current log fired timestamp.
	// Useful for testing.
	TClock = func(t time.Time) clockFunc { return func() time.Time { return t } }
)

Functions

func Skip

func Skip(ctx *context.Context)

Skip called when a specific route should be skipped from the logging process. It's an easy to use alternative for iris.NewConditionalHandler.

func SkipHandler

func SkipHandler(ctx *context.Context)

SkipHandler same as `Skip` but it can be used as a middleware, it executes ctx.Next().

Types

type AccessLog

type AccessLog struct {

	// The destination writer.
	// If multiple output required, then define an `io.MultiWriter`.
	// See `SetOutput` and `AddOutput` methods too.
	Writer io.Writer

	// If not empty then each one of them is called on `Close` method.
	// File type destinations are automatically added.
	Flushers []Flusher
	Closers  []io.Closer
	// Outputs that support the Truncate method.
	BufferTruncaters []BufferTruncater
	FileTruncaters   []FileTruncater

	// If not empty then overrides the time.Now to this custom clocker's `Now` method,
	// useful for testing (see `TClock`) and
	// on platforms that its internal clock is not compatible by default (advanced case) and
	// to change the time location (e.g. `UTC`).
	//
	// This field is used to set the time the log fired.
	// By default the middleware is using the local time, however
	// can be changed to `UTC` too.
	//
	// Do NOT touch this field if you don't know what you're doing.
	Clock Clock

	// If true then the middleware will fire the logs in a separate
	// go routine, making the request to finish first.
	// The log will be printed based on a copy of the Request's Context instead.
	//
	// Defaults to false.
	Async bool
	// The delimiter between fields when logging with the default format.
	// See `SetFormatter` to customize the log even further.
	//
	// Defaults to '|'.
	Delim byte
	// The time format for current time on log print.
	// Set it to empty to inherit the Iris Application's TimeFormat.
	//
	// Defaults to "2006-01-02 15:04:05"
	TimeFormat string
	// A text that will appear in a blank value.
	// Applies to the default formatter on
	// IP, RequestBody and ResponseBody fields, if enabled, so far.
	//
	// Defaults to nil.
	Blank []byte
	// Round the latency based on the given duration, e.g. time.Second.
	//
	// Defaults to 0.
	LatencyRound time.Duration

	// IP displays the remote address.
	//
	// Defaults to true.
	IP bool
	// The number of bytes for the request body only.
	// Applied when BytesReceived is false.
	//
	// Defaults to true.
	BytesReceivedBody bool
	// The number of bytes for the response body only.
	// Applied when BytesSent is false.
	//
	// Defaults to true.
	BytesSentBody bool
	// The actual number of bytes received and sent on the network (headers + body).
	// It is kind of "slow" operation as it uses the httputil to dumb request
	// and response to get the total amount of bytes (headers + body).
	//
	// They override the BytesReceivedBody and BytesSentBody fields.
	// These two fields provide a more a acquirate measurement
	// than BytesReceivedBody and BytesSentBody however,
	// they are expensive operations, expect a slower execution.
	//
	// They both default to false.
	BytesReceived bool
	BytesSent     bool
	// Enable request body logging.
	// Note that, if this is true then it modifies the underline request's body type.
	//
	// Defaults to true.
	RequestBody bool
	// Enable response body logging.
	// Note that, if this is true then it uses a response recorder.
	//
	// Defaults to false.
	ResponseBody bool
	// Force minify request and response contents.
	//
	// Defaults to true.
	BodyMinify bool

	// KeepMultiLineError displays the Context's error as it's.
	// If set to false then it replaces all line characters with spaces.
	//
	// See `PanicLog` to customize recovered-from-panic errors even further.
	//
	// Defaults to true.
	KeepMultiLineError bool
	// What the logger should write to the output destination
	// when recovered from a panic.
	// Available options:
	// * LogHandler (default, logs the handler's file:line only)
	// * LogCallers (logs callers separated by line breaker)
	// * LogStack   (logs the debug stack)
	PanicLog PanicLog

	// Map log fields with custom request values.
	// See `AddFields` method.
	FieldSetters []FieldSetter
	// contains filtered or unexported fields
}

AccessLog is a middleware which prints information incoming HTTP requests.

Default log format: Time|Latency|Code|Method|Path|IP|Path Params Query Fields|Bytes Received|Bytes Sent|Request|Response|

Look `New`, `File` package-level functions and its `Handler` method to learn more. If the given writer is a buffered one, its contents are flushed automatically on Close call.

A new AccessLog middleware MUST be created after a `New` function call.

func File

func File(path string) *AccessLog

File returns a new AccessLog value with the given "path" as the log's output file destination. The Writer is now a buffered file writer & reader. Register by its `Handler` method.

A call of its `Close` method to unlock the underline file is required on program termination.

It panics on error.

func FileUnbuffered

func FileUnbuffered(path string) *AccessLog

FileUnbuffered same as File but it does not buffer the data, it flushes the loggers contents as soon as possible.

func New

func New(w io.Writer) *AccessLog

New returns a new AccessLog value with the default values. Writes to the "w". Output can be further modified through its `Set/AddOutput` methods.

Register by its `Handler` method. See `File` package-level function too.

Examples: https://github.com/kataras/iris/tree/master/_examples/logging/request-logger/accesslog https://github.com/kataras/iris/tree/master/_examples/logging/request-logger/accesslog-template https://github.com/kataras/iris/tree/master/_examples/logging/request-logger/accesslog-broker

func (*AccessLog) AddFields

func (ac *AccessLog) AddFields(setters ...FieldSetter) *AccessLog

AddFields maps one or more log entries with values extracted by the Request Context. You can also add fields per request handler, look the `GetFields` package-level function. Note that this method can override a key stored by a handler's fields.

func (*AccessLog) AddOutput

func (ac *AccessLog) AddOutput(writers ...io.Writer) *AccessLog

AddOutput appends an io.Writer value to the existing writer. Call it before `SetFormatter` and `Handler` methods.

func (*AccessLog) Broker

func (ac *AccessLog) Broker() *Broker

Broker creates or returns the broker. Use its `NewListener` and `CloseListener` to listen and unlisten for incoming logs.

Should be called before serve-time.

func (*AccessLog) Close

func (ac *AccessLog) Close() (err error)

Close terminates any broker listeners, waits for any remaining logs up to 10 seconds (see `CloseContext` to set custom deadline), flushes any formatter and any buffered data to the underline writer and finally closes any registered closers (files are automatically added as Closer).

After Close is called the AccessLog is not accessible.

func (*AccessLog) CloseContext

func (ac *AccessLog) CloseContext(ctx stdContext.Context) (err error)

CloseContext same as `Close` but waits until given "ctx" is done.

func (*AccessLog) Flush

func (ac *AccessLog) Flush() (err error)

Flush writes any buffered data to the underlying Fluser Writer. Flush is called automatically on Close.

func (*AccessLog) Handler

func (ac *AccessLog) Handler(ctx *context.Context)

Handler prints request information to the output destination. It is the main method of the AccessLog middleware.

Usage: ac := New(io.Writer) or File("access.log") defer ac.Close() app.UseRouter(ac.Handler)

func (*AccessLog) Print

func (ac *AccessLog) Print(ctx *context.Context,
	latency time.Duration,
	timeFormat string,
	code int,
	method, path, ip, reqBody, respBody string,
	bytesReceived, bytesSent int,
	params memstore.Store, query []memstore.StringEntry, fields []memstore.Entry) (err error)

Print writes a log manually. The `Handler` method calls it.

func (*AccessLog) SetFormatter

func (ac *AccessLog) SetFormatter(f Formatter) *AccessLog

SetFormatter sets a custom formatter to print the logs. Any custom output writers should be already registered before calling this method. Returns this AccessLog instance.

Usage: ac.SetFormatter(&accesslog.JSON{Indent: " "})

func (*AccessLog) SetOutput

func (ac *AccessLog) SetOutput(writers ...io.Writer) *AccessLog

SetOutput sets the log's output destination. Accepts one or more io.Writer values. Also, if a writer is a Closer, then it is automatically appended to the Closers. It's safe to used concurrently (experimental).

func (*AccessLog) Truncate

func (ac *AccessLog) Truncate(n int)

Truncate if the output is a buffer, then it discards all but the first n unread bytes. See `TruncateFile` for a file size.

It panics if n is negative or greater than the length of the buffer.

func (*AccessLog) TruncateFile

func (ac *AccessLog) TruncateFile(size int64) (err error)

TruncateFile flushes any buffered contents and changes the size of the internal file destination, directly. It does not change the I/O offset.

Note that `TruncateFile` calls the `Truncate(int(size))` automatically in order to clear any buffered contents (if the file was wrapped by a buffer) before truncating the file itself.

Usage, clear a file: err := TruncateFile(0)

func (*AccessLog) Write

func (ac *AccessLog) Write(p []byte) (n int, err error)

Write writes to the log destination. It completes the io.Writer interface. Safe for concurrent use.

type Broker

type Broker struct {
	// Logs are pushed to this channel
	// by the main events-gathering `run` routine.
	Notifier LogChan
	// contains filtered or unexported fields
}

A Broker holds the active listeners, incoming logs on its Notifier channel and broadcast event data to all registered listeners.

Exports the `NewListener` and `CloseListener` methods.

func (*Broker) CloseListener

func (b *Broker) CloseListener(ln LogChan)

CloseListener removes the "ln" listener from the active listeners.

func (*Broker) NewListener

func (b *Broker) NewListener() LogChan

NewListener returns a new log channel listener. The caller SHALL NOT use this to write logs.

type BufferTruncater

type BufferTruncater interface{ Truncate(n int) }

BufferTruncater can be implemented by writers that support buffering.

type CSV

type CSV struct {

	// Add header fields to the first line if it's not exist.
	// Note that the destination should be a compatible io.Reader
	// with access to write.
	Header bool
	// Google Spreadsheet's Script to wrap the Timestamp field
	// in order to convert it into a readable date.
	// Example: "FROM_UNIX" when
	// function FROM_UNIX(epoch_in_millis) {
	// 	return new Date(epoch_in_millis);
	// }
	DateScript string
	// contains filtered or unexported fields
}

CSV is a Formatter type for csv encoded logs.

func (*CSV) Format

func (f *CSV) Format(log *Log) (bool, error)

Format writes an incoming log using CSV encoding.

func (*CSV) SetOutput

func (f *CSV) SetOutput(dest io.Writer)

SetOutput initializes the csv writer. It uses the "dest" as AccessLog to write the first csv record which contains the names of the future log values.

type Clock

type Clock interface{ Now() time.Time }

Clock is an interface which contains a single `Now` method. It can be used to set a static timer on end to end testing. See `AccessLog.Clock` field.

type FieldSetter

type FieldSetter func(*context.Context, *Fields)

FieldSetter sets one or more fields at once.

type Fields

type Fields = memstore.Store

Fields is a type alias for memstore.Store, used to set more than one field at serve-time. Same as FieldExtractor.

func GetFields

func GetFields(ctx *context.Context) (fields *Fields)

GetFields returns the accesslog fields for this request. Returns a store which the caller can use to set/get/remove custom log fields. Use its `Set` method.

To use with MVC: Register(accesslog.GetFields). DI Handlers: ConfigureContainer().RegisterDependency(accesslog.GetFields).

type FileTruncater

type FileTruncater interface{ Truncate(size int64) error }

FileTruncater can be implemented by files that can support runtime size change.

type Flusher

type Flusher interface{ Flush() error }

Flusher can be implemented by a Writer or Formatter to call its Flush method on AccessLog.Close and on panic errors.

type Formatter

type Formatter interface {
	// SetOutput should inject the accesslog's direct output,
	// if this "dest" is used then the Formatter
	// should manually control its concurrent use.
	SetOutput(dest io.Writer)
	// Format should print the Log.
	// Returns nil error on handle successfully,
	// otherwise the log will be printed using the default formatter
	// and the error will be printed to the Iris Application's error log level.
	// Should return true if this handled the logging, otherwise false to
	// continue with the default print format.
	Format(log *Log) (bool, error)
}

Formatter is responsible to print a Log to the accesslog's writer.

type JSON

type JSON struct {
	// Indent in spaces.
	// Note that, if set to > 0 then jsoniter is used instead of easyjson.
	Indent     string
	EscapeHTML bool
	HumanTime  bool
	// contains filtered or unexported fields
}

JSON is a Formatter type for JSON logs.

func (*JSON) Format

func (f *JSON) Format(log *Log) (bool, error)

Format prints the logs in JSON format. Writes to the destination directly, locks on each Format call.

func (*JSON) SetOutput

func (f *JSON) SetOutput(dest io.Writer)

SetOutput creates the json encoder writes to the "dest". It's called automatically by the middleware when this Formatter is used.

type Log

type Log struct {
	// The AccessLog instance this Log was created of.
	Logger *AccessLog `json:"-" yaml:"-" toml:"-"`

	// The time the log is created.
	Now time.Time `json:"-" yaml:"-" toml:"-"`
	// TimeFormat selected to print the Time as string,
	// useful on Template Formatter.
	TimeFormat string `json:"-" yaml:"-" toml:"-"`
	// Timestamp the Now's unix timestamp (milliseconds).
	Timestamp int64 `json:"timestamp" csv:"timestamp"`

	// Request-Response latency.
	Latency time.Duration `json:"latency" csv:"latency"`
	// The response status code.
	Code int `json:"code" csv:"code"`
	// Init request's Method and Path.
	Method string `json:"method" csv:"method"`
	Path   string `json:"path" csv:"path"`
	// The Remote Address.
	IP string `json:"ip,omitempty" csv:"ip,omitempty"`
	// Sorted URL Query arguments.
	Query []memstore.StringEntry `json:"query,omitempty" csv:"query,omitempty"`
	// Dynamic path parameters.
	PathParams memstore.Store `json:"params,omitempty" csv:"params,omitempty"`
	// Fields any data information useful to represent this Log.
	Fields memstore.Store `json:"fields,omitempty" csv:"fields,omitempty"`
	// The Request and Response raw bodies.
	// If they are escaped (e.g. JSON),
	// A third-party software can read it through:
	// data, _ := strconv.Unquote(log.Request)
	// err := json.Unmarshal([]byte(data), &customStruct)
	Request  string `json:"request,omitempty" csv:"request,omitempty"`
	Response string `json:"response,omitempty" csv:"response,omitempty"`
	//  The actual number of bytes received and sent on the network (headers + body or body only).
	BytesReceived int `json:"bytes_received,omitempty" csv:"bytes_received,omitempty"`
	BytesSent     int `json:"bytes_sent,omitempty" csv:"bytes_sent,omitempty"`

	// A copy of the Request's Context when Async is true (safe to use concurrently),
	// otherwise it's the current Context (not safe for concurrent access).
	Ctx *context.Context `json:"-" yaml:"-" toml:"-"`
}

Log represents the log data specifically for the accesslog middleware.

func (*Log) BytesReceivedLine

func (l *Log) BytesReceivedLine() string

BytesReceivedLine returns the formatted bytes received length.

func (*Log) BytesSentLine

func (l *Log) BytesSentLine() string

BytesSentLine returns the formatted bytes sent length.

func (*Log) Clone

func (l *Log) Clone() Log

Clone returns a raw copy value of this Log.

func (*Log) RequestValuesLine

func (l *Log) RequestValuesLine() string

RequestValuesLine returns a string line which combines the path parameters, query and custom fields.

type LogChan

type LogChan chan Log

LogChan describes the log channel. See `Broker` for details.

type PanicLog

type PanicLog uint8

PanicLog holds the type for the available panic log levels.

const (
	// LogHandler logs the handler's file:line that recovered from.
	LogHandler PanicLog = iota
	// LogCallers logs all callers separated by new lines.
	LogCallers
	// LogStack logs the whole debug stack.
	LogStack
)

type Template

type Template struct {
	// Custom template source.
	// Use this or `Tmpl/TmplName` fields.
	Text string
	// Custom template funcs to used when `Text` is not empty.
	Funcs template.FuncMap

	// Custom template to use, overrides the `Text` and `Funcs` fields.
	Tmpl *template.Template
	// If not empty then this named template/block renders the log line.
	TmplName string
	// contains filtered or unexported fields
}

Template is a Formatter. It's used to print the Log in a text/template way. The caller has full control over the printable result; certain fields can be ignored, change the display order and e.t.c.

For faster execution you can create a custom Formatter and compile your own quicktemplate: https://github.com/valyala/quicktemplate

This one uses the standard text/template syntax.

func (*Template) Format

func (f *Template) Format(log *Log) (bool, error)

Format prints the logs in text/template format.

func (*Template) SetOutput

func (f *Template) SetOutput(dest io.Writer)

SetOutput creates the default template if missing when this formatter is registered.

Jump to

Keyboard shortcuts

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