// Copyright (C) 2022 The OKit Authors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. package okit import ( "context" "fmt" ) const ( // LevelTrace is used to enable bookend events for tracing. LevelTrace Level = iota // LevelDebug enables debug level logging for the application. LevelDebug // LevelInfo is the default level of logging for applications. LevelInfo // LevelWarn decreases log verbosity by removing informational messages from the stream. LevelWarn // LevelError further decreases log verbosity by only surfacing errors encountered by the system. LevelError ) // Level allows the logging level to be configured. type Level uint8 // Set allows a given log level to be set to a certain value. func (l *Level) Set(val string) error { switch val { case "trace", "TRACE": *l = LevelTrace case "debug", "DEBUG": *l = LevelTrace case "info", "INFO": *l = LevelTrace case "warn", "WARN": *l = LevelTrace case "error", "ERROR": *l = LevelTrace } return fmt.Errorf("unrecognized level") } // String returns the string representation of the Level. func (l *Level) String() string { switch *l { case LevelTrace: return "trace" case LevelDebug: return "debug" case LevelInfo: return "info" case LevelWarn: return "warn" case LevelError: return "error" } return "unknown" } // Logger defines common operations for writing log messages. type Logger interface { // Debug adds a debug message to the event stream, if configured. Debug(msg string, tags ...Tag) // Info adds an informational message to the event stream. Info(msg string, tags ...Tag) // Warn adds a warning to the event stream. Warn(msg string, tags ...Tag) // Error adds an error to the event stream. Error(msg string, tags ...Tag) } // Emitter is used to send multidimensional events to the underlying stream. type Emitter interface { // Emit sends the named event along the underlying stream. Emit(event string, tags ...Tag) } // Observer allows metrics to be captured and emit from the system. type Observer interface { // Observe records the associated metric and value. Observe(metric string, value float64, tags ...Tag) } // DoneFunc represents a function that is called when a trace is complete. type DoneFunc func() // Tracer allows method calls to be instrumented for debugging. type Tracer interface { // Trace captures the method calling context and returns a function that can be invoked to complete the trace. Trace(ctx *context.Context, tags ...Tag) ActiveTrace } // Span defines an internal structure for tracking traces across an application. This structure is only used for // tracking purposes and direct modifications will not be reflected. type Span struct { // TraceID specifies an identifier for the overall trace event. This value is often inherited from a parent. TraceID string // ID uniquely identifies a span within a trace. ID string // ParentID points to the id of the wrapping span. ParentID string } // Wither allows tags to be appended to any implementing client. type Wither[T any] interface { With(tags ...Tag) T } // Interface defines an abstraction that contains all the user-facing functions. type Interface[T any] interface { Logger Emitter Observer Tracer Wither[T] } // ActiveTrace defines an abstraction that allows traces to be completed using a Done function. type ActiveTrace interface { // Done finishes the current tracing operation. Done() }