Documentation
¶
Index ¶
- func CloseOrJoin(errp *error, c io.Closer)
- func CloseOrLog(closer io.Closer)
- func CloseOrLogError(w io.Writer, c io.Closer)
- func CloseOrPanic(closer io.Closer)
- func FileByFormatHandler(folder string, maxFilesInFolder int, fileNameGenerator func() string) io.Writer
- func PrintHandler() io.Writer
- func RotatingFileHandler(folder, prefix string, opts ...RotatingFileOption) io.Writer
- func SetRuntimeDetailsProvider(fn func() string)
- func TelegramHandler(botToken, chatID, fileName string, labels ...string) io.Writer
- func TimestampedHandler(inner io.Writer, opts ...PrintOption) io.Writer
- func TimestampedPrintHandler(opts ...PrintOption) io.Writer
- func WithMinLevel(level LogLevel, handler io.Writer) io.Writer
- type FileLoggerOption
- func WithMaxFileCapacity(n uint32) FileLoggerOption
- func WithMaxFilesInFolder(n int) FileLoggerOption
- func WithPrinterMinLevel(level LogLevel) FileLoggerOption
- func WithPrinterOptions(opts ...PrintOption) FileLoggerOption
- func WithStdLogRedirect(level LogLevel) FileLoggerOption
- func WithTempDirFallback() FileLoggerOption
- func WithoutPrinter() FileLoggerOption
- type HookID
- type HttpError
- type LeveledHandler
- type LogLevel
- type Logger
- func (l *Logger) Hook(writer io.Writer, level LogLevel, additional ...LogLevel) HookID
- func (l *Logger) Panic(level LogLevel, args ...any)
- func (l *Logger) Panicf(level LogLevel, format string, args ...any)
- func (l *Logger) Print(level LogLevel, args ...any)
- func (l *Logger) Printf(level LogLevel, format string, args ...any)
- func (l *Logger) SetMinLevel(level LogLevel)
- func (l *Logger) StdLog(level LogLevel, prefix string) *log.Logger
- func (l *Logger) Unhook(id HookID)
- func (l *Logger) Write(message []byte) (int, error)
- func (l *Logger) WriteLog(level LogLevel, message []byte) (int, error)
- func (l *Logger) WriterAs(level LogLevel) io.Writer
- type PrintOption
- type PublicDetailsError
- type PublicError
- type RotatingFileOption
- type StackTraceError
- type TraceError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloseOrJoin ¶ added in v1.0.6
CloseOrJoin closes c and joins any close error into *errp using errors.Join, which drops nil arguments and returns nil when all arguments are nil. The intended usage is
defer CloseOrJoin(&err, c)
inside a function with a named (... err error) return — the deferred call runs after the function body and joins the close error into whatever err holds at that point. A nil errp means the close error has nowhere to be stored; c is still closed and the error is silently discarded. A nil c is a no-op.
func CloseOrLog ¶
CloseOrLog closes the closer and logs the error if there is one.
func CloseOrLogError ¶ added in v1.0.6
CloseOrLogError closes c and, if Close returns a non-nil error and w is non-nil, writes the error message followed by a newline to w. It differs from CloseOrLog in that it writes to the caller-supplied writer rather than the standard library log package, making it suitable for structured logging (e.g. logger.WriterAs(level)). A nil w means the write is skipped but c is still closed. A nil c is a no-op. The write error is intentionally discarded — writing to a logger is the documented fmt.Fprint*-to-logger exception to the no-skipped-errors rule.
func CloseOrPanic ¶
CloseOrPanic closes the closer and panics if there is an error.
func FileByFormatHandler ¶
func FileByFormatHandler(folder string, maxFilesInFolder int, fileNameGenerator func() string) io.Writer
FileByFormatHandler save messages to files by format. The file name is generated by fileNameGenerator. The folder is the directory where the files are saved. The maxFilesInFolder is the maximum number of files in the folder. No fresh-start variant exists for this handler; see RotatingFileHandler's WithFreshStart for an analogous feature on the index-based handler (there the construction-time target is known, whereas here the name is generated per-write by fileNameGenerator).
func PrintHandler ¶
PrintHandler writes each message to os.Stdout as a plain line, trimming surrounding whitespace and appending a single newline. It adds no timestamp; for the timestamped console sink (which is the default when NewLogger is given no handlers) use TimestampedPrintHandler. The returned writer is mutex-guarded; the logger never calls its Write concurrently.
func RotatingFileHandler ¶ added in v1.0.6
func RotatingFileHandler(folder, prefix string, opts ...RotatingFileOption) io.Writer
RotatingFileHandler saves messages to files by number. The file name is generated from prefix and an incrementing index (e.g. prefix.00000001.log). When a file exceeds the maximum size the handler moves to the next index and prunes the oldest files so that no more than the configured maximum remain in folder. The handler appends to files and ring-prunes the oldest ones; it never overwrites a file's existing contents unless WithFreshStart is passed.
On construction the handler resumes at the highest existing index for prefix in folder (index 1 when none exist or WithFreshStart is set) and seeds the in-memory size counter from that file's on-disk size, so the first write after a restart accounts for existing content instead of writing into the oldest file and letting pruning delete the newest data. Filenames in folder that do not match the exact prefix.<8 hex>.log shape are ignored. Any stat/glob error encountered while resolving the resume point is stashed and joined into the first Write's return value.
Defaults: max file size 5 MiB, max files 7. Override with WithMaxFileSize and WithMaxFiles; use WithFreshStart to begin each run from a truncated index-1 file. FileByFormatHandler is the sibling for filename-generator-driven rotation and has no fresh-start variant (its target name is not known until the first write).
The returned writer is mutex-guarded; the logger never calls its Write concurrently.
func SetRuntimeDetailsProvider ¶ added in v1.0.6
func SetRuntimeDetailsProvider(fn func() string)
SetRuntimeDetailsProvider installs a process-wide provider that supplies additional runtime detail text appended to every StackTraceError's Runtime() output. The provider is called at most once per process; its return value is cached for the lifetime of the process, mirroring the caching behaviour of the built-in os/arch/Go-version runtime string.
Call this at startup, before any StackTraceError is constructed. Calling it after a StackTraceError has been constructed has NO effect, because the runtime string is cached on first use (see Runtime() docs). Calling it more than once: the last call before the cache is populated wins; calls after the cache is populated are no-ops.
The provider must be safe to call from any goroutine. Loginjector calls it under the same sync.Once that guards the built-in runtime string, so the provider sees no concurrent invocation; once cached, Runtime() never calls it again.
Provider must not panic; a panic is recovered and the built-in base string (os/arch/go version) is used without the extra detail.
Only one provider is active at a time; a subsequent SetRuntimeDetailsProvider call before the cache is populated replaces the first with no composition.
The provider's return value is appended verbatim to error strings; avoid control characters in the return value.
Pass nil to clear a previously-set provider (useful in tests).
func TelegramHandler ¶
func TimestampedHandler ¶ added in v1.0.6
func TimestampedHandler(inner io.Writer, opts ...PrintOption) io.Writer
TimestampedHandler wraps inner so each message is prefixed with a leading timestamp before being forwarded to inner, indenting the continuation lines of a multi-line message so the body reads as a block. It is the composable form of TimestampedPrintHandler: any io.Writer (a file handler, a buffer, another sink) can be given sink-side timestamps. The returned writer is mutex-guarded; the logger never calls its Write concurrently.
The timestamp layout defaults to "2006/01/02 15:04:05". The first line of a message is prefixed with "<timestamp> "; subsequent lines are indented by the same width so multi-line payloads read as a visual block. Trailing whitespace and newlines are trimmed from the input before formatting; the output always ends with exactly one newline. An empty or whitespace-only input produces a single "<timestamp>\n" line.
WithTimeLayout and withClock apply; WithOutput is ignored because the sink is the explicit inner argument. Use TimestampedPrintHandler when you want the os.Stdout instantiation with WithOutput support.
func TimestampedPrintHandler ¶ added in v1.0.6
func TimestampedPrintHandler(opts ...PrintOption) io.Writer
TimestampedPrintHandler prints each message to stdout with a leading timestamp, indenting the continuation lines of a multi-line message so the body reads as a block. Unlike PrintHandler, which writes to stdout via a plain writer, this handler adds a timestamp; the sink is os.Stdout by default and overridable with WithOutput. The returned writer is mutex-guarded; the logger never calls its Write concurrently. It is the os.Stdout instantiation of TimestampedHandler.
The timestamp layout defaults to "2006/01/02 15:04:05". The first line of a message is prefixed with "<timestamp> "; subsequent lines are indented by the same width so multi-line payloads read as a visual block. Trailing whitespace and newlines are trimmed from the input before formatting; the output always ends with exactly one newline. An empty or whitespace-only input produces a single "<timestamp>\n" line.
func WithMinLevel ¶ added in v1.0.6
WithMinLevel wraps handler so that Logger treats it as a LeveledHandler with the given minimum level. The returned writer forwards Write calls to handler unchanged; the only added behaviour is the MinLevel() method that Logger.WriteLog reads via interface assertion. Use this to give one handler a threshold distinct from the parent Logger's minimumLogLevel — for example, to send only high-severity messages to the console while sending everything to a file:
file := loginjector.RotatingFileHandler("./logs", "app")
console := loginjector.WithMinLevel(levels.Warning, loginjector.TimestampedPrintHandler())
logger := loginjector.NewLogger(levels.Info, file, console)
The returned writer is itself thread-safe via Logger's existing ensureThreadSafe wrapping at registration. Calling WithMinLevel on an already-leveled writer replaces the inner MinLevel().
Types ¶
type FileLoggerOption ¶ added in v1.0.6
type FileLoggerOption func(*fileLoggerConfig)
FileLoggerOption configures NewFileLogger.
func WithMaxFileCapacity ¶ added in v1.0.6
func WithMaxFileCapacity(n uint32) FileLoggerOption
WithMaxFileCapacity overrides the maximum size of a single log file in bytes before the handler rotates to the next file. The default is 5 MiB (5 * 1024 * 1024). The underlying RotatingFileHandler takes a uint32, so values larger than math.MaxUint32 are not valid; pass a reasonable capacity.
func WithMaxFilesInFolder ¶ added in v1.0.6
func WithMaxFilesInFolder(n int) FileLoggerOption
WithMaxFilesInFolder overrides the maximum number of rotated log files retained in the log folder. Older files beyond the limit are pruned on rotation. The default is 7.
func WithPrinterMinLevel ¶ added in v1.0.6
func WithPrinterMinLevel(level LogLevel) FileLoggerOption
WithPrinterMinLevel overrides the threshold at which the console printer emits messages, decoupling it from the file-handler threshold (minLevel). When not set, the printer fires at minLevel (current behaviour). When set, the console printer fires at level >= this value while the file handler continues to fire at level >= minLevel.
Has no effect when combined with WithoutPrinter — WithoutPrinter wins.
Implemented by wrapping the printer handler in WithMinLevel before adding it to the Logger handler list; the per-handler gate in Logger.WriteLog does the rest.
func WithPrinterOptions ¶ added in v1.0.6
func WithPrinterOptions(opts ...PrintOption) FileLoggerOption
WithPrinterOptions forwards PrintOption values to the TimestampedPrintHandler created by NewFileLogger. Has no effect when combined with WithoutPrinter.
func WithStdLogRedirect ¶ added in v1.0.6
func WithStdLogRedirect(level LogLevel) FileLoggerOption
WithStdLogRedirect redirects the standard library log package output to the new logger at the given level and sets log.Flags to 0. This option is OFF by default because log.SetOutput mutates global process state shared by every package in the binary — opting in is a conscious, explicit decision. If WithStdLogRedirect is passed more than once, the last call wins. If two NewFileLogger calls in the same process both use this option, the second call silently wins: log.SetOutput is global and the first logger will no longer receive standard library log output.
func WithTempDirFallback ¶ added in v1.0.6
func WithTempDirFallback() FileLoggerOption
WithTempDirFallback enables the temp-directory fallback: when the folder argument to NewFileLogger is empty, logs are written under filepath.Join(os.TempDir(), "logs") instead of returning an error. This option is OFF by default — an empty folder without this option is a hard error, so logs never silently land in an unexpected location. Note that the shared temp path is a residual risk: on multi-user systems another process could create the directory before NewFileLogger and own it with permissive permissions; NewFileLogger calls os.Chmod after MkdirAll to enforce 0750, but there is a brief window between directory creation and the chmod call.
func WithoutPrinter ¶ added in v1.0.6
func WithoutPrinter() FileLoggerOption
WithoutPrinter disables the timestamped stdout printer that NewFileLogger attaches by default. Use this when you want only the rotated file output and no console echo.
type HttpError ¶
HttpError is an error that provides an HTTP status code.
func NewHttpError ¶
NewHttpError creates a new HttpError with the given status code.
func WrapHttpError ¶ added in v1.0.6
WrapHttpError creates an HttpError that carries an underlying cause. StatusCode() returns code, Error() returns the HTTP status text followed by the cause detail, and errors.Unwrap traverses to cause. For standard HTTP codes with a nil cause, Error() matches NewHttpError(code). For unrecognised codes where http.StatusText returns an empty string, Error() falls back to "HTTP <code>" so the string is never empty — this diverges from NewHttpError(code), which returns "" for such codes; switching from NewHttpError to WrapHttpError(code, nil) on a bogus code therefore changes the Error() output.
type LeveledHandler ¶ added in v1.0.6
LeveledHandler is an optional interface a handler may implement to declare a minimum log level distinct from the parent Logger's minimumLogLevel. When a handler implements LeveledHandler, Logger.WriteLog uses its MinLevel() instead of Logger.minimumLogLevel for the per-handler gate. Handlers that do not implement LeveledHandler keep the historical behaviour — they fire when level >= Logger.minimumLogLevel.
MinLevel must be safe to call concurrently and must return the same value for the lifetime of the handler — Logger caches no result.
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger is describing the logger structure and its methods
func NewFileLogger ¶ added in v1.0.6
func NewFileLogger(folder, prefix string, minLevel LogLevel, opts ...FileLoggerOption) (*Logger, error)
NewFileLogger builds a Logger that writes to size-rotated files under folder and, by default, mirrors every message at or above minLevel to a timestamped stdout printer (TimestampedPrintHandler). The printer fires as a handler (level >= minLevel), not a hook, so its gating matches the file handler exactly.
File lines are timestamped: the rotated file handler is wrapped in TimestampedHandler, so each on-disk line is "<timestamp> <message>" (layout "2006/01/02 15:04:05"), not the bare message. The console printer and the file handler are two separate sinks, each stamped exactly once.
The standard library log package is NOT redirected unless WithStdLogRedirect is passed — that redirect mutates global process state. An empty folder is rejected unless WithTempDirFallback is passed, in which case logs land under filepath.Join(os.TempDir(), "logs"). An empty prefix is always rejected because a hidden dotfile log (prefix ".") is a footgun.
Defaults: maxFileCapacity = 5 MiB, maxFilesInFolder = 7, printer ON, std-log redirect OFF, temp fallback OFF.
func NewLogger ¶
NewLogger creates a new logger with the given minimum log level and handlers. If no handlers are provided, a default TimestampedPrintHandler (timestamped stdout) is added. Each handler is wrapped so the logger never calls its Write concurrently, which makes logging safe from multiple goroutines even with non-thread-safe handlers.
func (*Logger) Hook ¶
Hook registers writer to fire on an EXACT match of any of the given levels (level plus additional), regardless of the logger's minimum level. Duplicate levels are collapsed to a single registration, so Hook(w, X, X) writes to w once per matching WriteLog, not twice. The returned HookID removes every registration created by this call when passed to Unhook.
Hooks match on exact equality, not a threshold: a hook on level X does NOT fire for a message logged at level X+1. To alert on "level >= X" — the common case for routing high-severity messages to an out-of-band sink — register a WithMinLevel(X, writer) handler instead of enumerating exact levels, because an enumeration that omits one level silently drops that level's messages.
The returned HookID is unique only within this logger; do not persist or compare it against a fixed format.
func (*Logger) Panic ¶ added in v1.0.6
Panic writes a log message at the given level and then panics with the message string. The panic is recoverable: deferred functions run and callers may use recover() to catch it. It does NOT call os.Exit — process death is not guaranteed.
func (*Logger) Panicf ¶ added in v1.0.6
Panicf writes a formatted log message at the given level and then panics with the message string. The panic is recoverable: deferred functions run and callers may use recover() to catch it. It does NOT call os.Exit — process death is not guaranteed.
func (*Logger) SetMinLevel ¶
SetMinLevel sets the minimum log level
func (*Logger) StdLog ¶ added in v1.0.6
StdLog returns a standard-library *log.Logger that writes through this logger at the given level, with the given prefix. It is configured with log.Lmsgprefix and no date/time flags: the emitter contributes only the prefix, and any timestamp is added by the sink (e.g. TimestampedPrintHandler or TimestampedHandler), so a line is never stamped twice. Use it to hand a *log.Logger to code that expects one — for example a database driver's logger — without hand-wiring the flags:
dbLog := logger.StdLog(levels.Info, "sqlite ")
Each call returns a fresh *log.Logger over a fresh writer; the returned logger routes through WriteLog, which serializes writes per sink.
func (*Logger) WriteLog ¶
WriteLog writes a log message at the given level to all matching sinks.
Hooks fire on an exact level match regardless of minimumLogLevel. Handlers fire only when level >= minimumLogLevel. When no sinks match (below the minimum and no matching hooks), WriteLog returns (0, nil). When exactly one sink matches it is written inline (no goroutine overhead). Two or more sinks run concurrently, each in its own goroutine, with errors joined via errors.Join.
WriteLog holds the read lock for the entire duration so it is safe to call concurrently with Hook/Unhook/SetMinLevel.
type PrintOption ¶ added in v1.0.6
type PrintOption func(*printConfig)
PrintOption configures TimestampedPrintHandler.
func WithOutput ¶ added in v1.0.6
func WithOutput(w io.Writer) PrintOption
WithOutput overrides the sink used by TimestampedPrintHandler. The default is os.Stdout. This is primarily intended to redirect output for testing, but it is a legitimate consumer need (e.g. writing timestamped messages to a file instead of stdout).
func WithTimeLayout ¶ added in v1.0.6
func WithTimeLayout(layout string) PrintOption
WithTimeLayout overrides the timestamp layout used by TimestampedPrintHandler. The default layout is "2006/01/02 15:04:05".
type PublicDetailsError ¶ added in v1.0.6
type PublicDetailsError interface {
PublicError
// Details returns the joined client-safe text. It is an alias of
// PublicMessage and always returns the same value.
Details() string
}
PublicDetailsError extends PublicError with a Details accessor that returns the same client-safe text as PublicMessage. It is the return type of NewPublicErrorDetails and exists so callers using the variadic constructor have an accessor name that matches the common consumer convention.
func NewPublicErrorDetails ¶ added in v1.0.6
func NewPublicErrorDetails(parts ...string) PublicDetailsError
NewPublicErrorDetails creates a PublicDetailsError by joining the given parts with a single space. The result has no internal cause; Error() and PublicMessage() both return the joined string. It is a convenience for the common pattern of building a public message from several parts and is semantically identical to NewPublicError(strings.Join(parts, " "), nil).
type PublicError ¶ added in v1.0.6
type PublicError interface {
// PublicMessage returns the client-safe text. It never includes any detail
// from the internal cause, even if the public string is empty.
PublicMessage() string
error
}
PublicError separates a user-safe public message from the internal cause. Error() returns the internal detail for logging; PublicMessage() returns only the text that is safe to expose to clients and never leaks the internal cause.
func NewPublicError ¶ added in v1.0.6
func NewPublicError(public string, cause error) PublicError
NewPublicError creates a PublicError from a client-safe message and an internal cause. Error() returns the cause's error text for logging, falling back to the public message only when cause is nil. PublicMessage() always returns only the public string. Unwrap returns cause, so errors.Is and errors.As traverse to it.
type RotatingFileOption ¶ added in v1.0.6
type RotatingFileOption func(*rotatingFileConfig)
RotatingFileOption configures RotatingFileHandler.
func WithFreshStart ¶ added in v1.0.6
func WithFreshStart() RotatingFileOption
WithFreshStart makes the handler remove every existing prefix.<8 hex>.log file in folder once at construction, before the first write, so each process run begins with a genuinely empty ring at index 1. Existing rotated content is permanently destroyed — this is the intended behaviour; omit the option to resume and preserve prior content across restarts. Files in folder that do not match the prefix.<8 hex>.log shape are left untouched.
A missing file or folder is a no-op: no file is created at construction, and the first write creates index-1. Any removal error is stashed and surfaced on the first Write's return value, then cleared. WithFreshStart forces the starting index to 1 and the seeded size to 0, overriding the resume-at-highest-index behaviour.
func WithMaxFileSize ¶ added in v1.0.6
func WithMaxFileSize(n uint32) RotatingFileOption
WithMaxFileSize overrides the maximum size of a single log file in bytes before the handler rotates to the next index. The default is 5 MiB (5 << 20).
func WithMaxFiles ¶ added in v1.0.6
func WithMaxFiles(n int) RotatingFileOption
WithMaxFiles overrides the maximum number of rotated log files retained in the folder. Older files beyond the limit are pruned on rotation. The default is 7.
type StackTraceError ¶ added in v1.0.6
type StackTraceError interface {
// Stack returns the full debug.Stack() output captured at construction time.
// The output contains absolute build-host file paths — do not forward it to
// untrusted clients or HTTP responses.
Stack() string
// Runtime returns a string describing the OS, architecture, and Go version,
// computed once on first use and cached for the process lifetime — every
// StackTraceError value shares the same string. If
// SetRuntimeDetailsProvider was called with a non-nil function before any
// StackTraceError was constructed, the provider's output is appended to the
// built-in os/arch/go descriptor.
Runtime() string
error
}
StackTraceError captures a full stack trace and runtime environment details at the point of construction. Error() returns only the message and cause for compact log lines; the full stack is available on demand via Stack(). Runtime details (OS, arch, Go version) are cached once for the process lifetime.
func NewStackTraceError ¶ added in v1.0.6
func NewStackTraceError() StackTraceError
NewStackTraceError creates a StackTraceError with the full call-stack captured at this call site. Error() returns an empty string because no message is supplied — call Stack() for the full trace. The empty Error() means this value contributes no text when joined via errors.Join or wrapped via fmt.Errorf("%w"); use NewStackTraceErrorf when you need a non-empty error string in the chain. Stack() contains absolute build-host file paths; do not forward it to untrusted clients.
func NewStackTraceErrorf ¶ added in v1.0.6
func NewStackTraceErrorf(format string, args ...any) StackTraceError
NewStackTraceErrorf creates a StackTraceError with a formatted message and the full call-stack captured at this call site. Error() returns the message only; use Stack() for the full trace.
func WrapStackTraceError ¶ added in v1.0.6
func WrapStackTraceError(cause error, format string, args ...any) StackTraceError
WrapStackTraceError creates a StackTraceError with a formatted message, the full call-stack captured at this call site, and an explicit cause. errors.Unwrap, errors.Is, and errors.As traverse to cause. Passing a nil cause is safe. The message is rendered with fmt.Sprintf — do NOT use %w in the format string; use the cause argument for wrapping.
type TraceError ¶
TraceError is an error that provides a stack trace.
func NewTraceError ¶
func NewTraceError() TraceError
NewTraceError creates a new TraceError with the current stack trace.
func NewTraceErrorf ¶ added in v1.0.6
func NewTraceErrorf(format string, args ...any) TraceError
NewTraceErrorf creates a TraceError with a formatted message and the current call-site line. The message is built via fmt.Errorf, so a %w verb in format wraps the corresponding argument and errors.Is/errors.As traverse to it (through one intermediate fmt.Errorf node — Unwrap is always non-nil for the value produced here; it just terminates with nil when no %w was used). To have Unwrap return your cause directly with a single hop, use WrapTraceError. The stack line is captured at the point of this call, not inside any helper.
func WrapTraceError ¶ added in v1.0.6
func WrapTraceError(cause error, format string, args ...any) TraceError
WrapTraceError creates a TraceError with a formatted message, the current call-site line, and an explicit cause. errors.Unwrap, errors.Is, and errors.As traverse to cause. Passing a nil cause is safe; Unwrap returns nil. The message is rendered with fmt.Sprintf — do NOT use %w in the format string, it would produce a "%!w(...)" garbage token; rely on the cause argument for wrapping, or use NewTraceErrorf if you need %w in the format itself.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package httptap is the opt-in HTTP-traffic tap for github.com/prorochestvo/loginjector.
|
Package httptap is the opt-in HTTP-traffic tap for github.com/prorochestvo/loginjector. |
|
synctest
Package synctest provides a mutex-guarded bytes.Buffer for the loginjector test suites.
|
Package synctest provides a mutex-guarded bytes.Buffer for the loginjector test suites. |
|
Package levels provides an optional preset of named severity constants for the loginjector.LogLevel type.
|
Package levels provides an optional preset of named severity constants for the loginjector.LogLevel type. |