Documentation
¶
Index ¶
- Variables
- func GetGlobalOutput() io.Writer
- func GetWriter(ctx context.Context) io.Writer
- func IsComponentVisible(component string, cfg *Config) bool
- func NewLogger(component string) *logrus.Entry
- func Reset()
- func SetGlobalOutput(w io.Writer)
- func StructToLogrusFields(v interface{}) logrus.Fields
- func WithWriter(ctx context.Context, writer io.Writer) context.Context
- type ComponentFilteringConfig
- type Config
- type FileHook
- type FileSinkConfig
- type FormatConfig
- type LogEntry
- func (e *LogEntry) Emit()
- func (e *LogEntry) Err(err error) *LogEntry
- func (e *LogEntry) Field(key string, value interface{}) *LogEntry
- func (e *LogEntry) Fields(fields map[string]interface{}) *LogEntry
- func (e *LogEntry) Icon(icon string) *LogEntry
- func (e *LogEntry) Log(ctx context.Context)
- func (e *LogEntry) NoIcon() *LogEntry
- func (e *LogEntry) Pretty(styled string) *LogEntry
- func (e *LogEntry) PrettyOnly() *LogEntry
- func (e *LogEntry) StructuredOnly() *LogEntry
- type OverrideOptions
- type PrettyLogger
- func (p *PrettyLogger) Blank()
- func (p *PrettyLogger) BlankCtx(ctx context.Context)
- func (p *PrettyLogger) Box(title, content string)
- func (p *PrettyLogger) BoxCtx(ctx context.Context, title, content string)
- func (p *PrettyLogger) Code(content string)
- func (p *PrettyLogger) CodeCtx(ctx context.Context, content string)
- func (p *PrettyLogger) Divider()
- func (p *PrettyLogger) DividerCtx(ctx context.Context)
- func (p *PrettyLogger) ErrorPretty(message string, err error)
- func (p *PrettyLogger) ErrorPrettyCtx(ctx context.Context, message string, err error)
- func (p *PrettyLogger) Field(key string, value interface{})
- func (p *PrettyLogger) FieldCtx(ctx context.Context, key string, value interface{})
- func (p *PrettyLogger) InfoPretty(message string)
- func (p *PrettyLogger) InfoPrettyCtx(ctx context.Context, message string)
- func (p *PrettyLogger) KeyValues(pairs map[string]interface{})
- func (p *PrettyLogger) KeyValuesCtx(ctx context.Context, pairs map[string]interface{})
- func (p *PrettyLogger) List(items []string)
- func (p *PrettyLogger) ListCtx(ctx context.Context, items []string)
- func (p *PrettyLogger) Path(label string, path string)
- func (p *PrettyLogger) PathCtx(ctx context.Context, label string, path string)
- func (p *PrettyLogger) Progress(message string)
- func (p *PrettyLogger) ProgressCtx(ctx context.Context, message string)
- func (p *PrettyLogger) Section(title string)
- func (p *PrettyLogger) SectionCtx(ctx context.Context, title string)
- func (p *PrettyLogger) Status(status, message string)
- func (p *PrettyLogger) StatusCtx(ctx context.Context, status, message string)
- func (p *PrettyLogger) Success(message string)
- func (p *PrettyLogger) SuccessCtx(ctx context.Context, message string)
- func (p *PrettyLogger) WarnPretty(message string)
- func (p *PrettyLogger) WarnPrettyCtx(ctx context.Context, message string)
- func (p *PrettyLogger) WithWriter(w io.Writer) *PrettyLogger
- type PrettyStyles
- type TextFormatter
- type UnifiedLogger
- func (u *UnifiedLogger) Component() string
- func (u *UnifiedLogger) Debug(msg string) *LogEntry
- func (u *UnifiedLogger) Error(msg string) *LogEntry
- func (u *UnifiedLogger) Info(msg string) *LogEntry
- func (u *UnifiedLogger) Progress(msg string) *LogEntry
- func (u *UnifiedLogger) Status(msg string) *LogEntry
- func (u *UnifiedLogger) Success(msg string) *LogEntry
- func (u *UnifiedLogger) Warn(msg string) *LogEntry
- func (u *UnifiedLogger) WithPretty() *PrettyLogger
- func (u *UnifiedLogger) WithStructured() *logrus.Entry
- type VersionFields
- type VisibilityReason
- type VisibilityResult
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultGroups = map[string][]string{
"grove-ecosystem": {
"grove-agent-logs",
"grove-context",
"grove-core",
"grove-docgen",
"grove-flow",
"grove-gemini",
"grove-hooks",
"grove-mcp",
"grove-meta",
"grove-notebook",
"grove-notifications",
"grove-nvim",
"grove-openai",
"grove-proxy",
"grove-sandbox",
"grove-tend",
"grove-tmux",
},
"ai": {
"grove-gemini",
"grove-openai",
"grove-context",
},
}
DefaultGroups contains built-in component groups that users can reference in show/hide without defining them. User-defined groups take precedence.
var DefaultHide = []string{"grove-ecosystem"}
DefaultHide is the default list of components/groups to hide when no show or hide rules are configured. The current project is still visible due to ShowCurrentProject defaulting to true.
Functions ¶
func GetGlobalOutput ¶
GetGlobalOutput returns the singleton instance of the global writer. All logging packages should be initialized with this writer.
func GetWriter ¶
GetWriter retrieves the job-specific output writer from context. It falls back to the global logger output if no writer is found.
func IsComponentVisible ¶
IsComponentVisible determines if a component should be visible in console logs based on the provided configuration.
func NewLogger ¶
NewLogger creates and returns a pre-configured logger for a specific component. It uses a singleton pattern per component to avoid re-initializing.
Example ¶
package main
import (
"github.com/grovetools/core/logging"
"github.com/sirupsen/logrus"
)
func main() {
// Create a logger for your component
log := logging.NewLogger("my-component")
// Use it for various log levels
log.Debug("Debug information")
log.Info("Starting process")
log.Warn("Resource usage high")
log.Error("Connection failed")
// Add structured fields
log.WithFields(logrus.Fields{
"user_id": 123,
"action": "login",
}).Info("User logged in")
// Use WithField for single fields
log.WithField("file", "/path/to/file.txt").Info("Processing file")
// Use WithError for errors
// err := someFunction()
// log.WithError(err).Error("Operation failed")
}
Example (Configuration) ¶
package main
import (
"github.com/grovetools/core/logging"
)
func main() {
// Configuration via grove.yml:
//
// logging:
// level: debug # Set log level
// report_caller: true # Include file/line info
// file:
// enabled: true
// path: /var/log/grove/app.log
// format:
// preset: json # Use JSON output format
// Or via environment variables:
// GROVE_LOG_LEVEL=debug
// GROVE_LOG_CALLER=true
log := logging.NewLogger("configured-app")
log.Info("This will respect the configuration")
}
Example (MultipleComponents) ¶
package main
import (
"github.com/grovetools/core/logging"
)
func main() {
// Different components can have their own loggers
// but they share the same configuration
dbLog := logging.NewLogger("database")
apiLog := logging.NewLogger("api-server")
authLog := logging.NewLogger("auth")
// Each log entry will be tagged with its component
dbLog.Info("Connected to database")
apiLog.Info("Server started on port 8080")
authLog.Warn("Invalid login attempt")
// Output will show:
// [INFO] [database] Connected to database
// [INFO] [api-server] Server started on port 8080
// [WARN] [auth] Invalid login attempt
}
func Reset ¶
func Reset()
Reset clears the logger cache and resets the init state. This is primarily useful for testing when you need to reinitialize loggers with different configurations.
func SetGlobalOutput ¶
SetGlobalOutput sets the output destination for all loggers that use it. This is the central function for redirecting logs in the TUI.
func StructToLogrusFields ¶
StructToLogrusFields converts a struct with verbosity tags to logrus.Fields including a _verbosity metadata field that maps field names to verbosity levels
Types ¶
type ComponentFilteringConfig ¶
type ComponentFilteringConfig struct {
// Only is a strict whitelist. If set, only logs from these components/groups will be shown.
Only []string `yaml:"only,omitempty" toml:"only,omitempty"`
// Show ensures logs from these components/groups are visible, overriding any 'hide' rules.
// It does not act as a whitelist.
Show []string `yaml:"show,omitempty" toml:"show,omitempty"`
// Hide is a blacklist of components or groups to silence.
// This is ignored if 'only' is set. 'show' overrides 'hide'.
Hide []string `yaml:"hide,omitempty" toml:"hide,omitempty"`
}
ComponentFilteringConfig defines rules for showing/hiding logs from components.
type Config ¶
type Config struct {
// Level is the minimum log level to output (e.g., "debug", "info", "warn", "error").
// Can be overridden by the GROVE_LOG_LEVEL environment variable.
Level string `yaml:"level" toml:"level" jsonschema:"default=info"`
// ReportCaller, if true, includes the file, line, and function name in the log output.
// Can be enabled with the GROVE_LOG_CALLER=true environment variable.
ReportCaller bool `yaml:"report_caller" toml:"report_caller" jsonschema:"default=true"`
// LogStartup, if true, logs "Grove binary started" on first logger initialization.
// Defaults to false.
LogStartup bool `yaml:"log_startup" toml:"log_startup"`
// File configures logging to a file.
File FileSinkConfig `yaml:"file" toml:"file"`
// Format configures the appearance of the log output.
Format FormatConfig `yaml:"format" toml:"format"`
// Groups defines named collections of component loggers for easy filtering.
// Example:
// groups:
// ai: [grove-gemini, grove-context]
// devops: [grove-proxy, grove-deploy]
Groups map[string][]string `yaml:"groups,omitempty" toml:"groups,omitempty"`
// ComponentFiltering contains all rules for filtering logs by component.
ComponentFiltering *ComponentFilteringConfig `yaml:"component_filtering,omitempty" toml:"component_filtering,omitempty"`
// ShowCurrentProject, if true (default), always shows logs from the current project
// regardless of show/hide settings. The current project is determined from grove.yml name.
ShowCurrentProject *bool `yaml:"show_current_project,omitempty" toml:"show_current_project,omitempty"`
}
Config defines the structure for logging configuration in grove.yml.
func GetDefaultLoggingConfig ¶
func GetDefaultLoggingConfig() Config
GetDefaultLoggingConfig returns a Config with sensible defaults that enable file logging and caller reporting out of the box. This allows `core logs` to work immediately without any user configuration.
type FileHook ¶
type FileHook struct {
Writer io.Writer
LogLevels []logrus.Level
Formatter logrus.Formatter
// contains filtered or unexported fields
}
FileHook is a logrus hook for writing logs to a file with a specific formatter. It includes a mutex to handle concurrent writes from different tool processes.
type FileSinkConfig ¶
type FileSinkConfig struct {
Enabled bool `yaml:"enabled" toml:"enabled" jsonschema:"default=true"`
// Path is the full path to the log file.
Path string `yaml:"path" toml:"path"`
Format string `yaml:"format,omitempty" toml:"format,omitempty" jsonschema:"default=json"` // "text" or "json" (default)
}
FileSinkConfig configures the file logging sink.
type FormatConfig ¶
type FormatConfig struct {
// Preset can be "default" (rich text), "simple" (minimal text), or "json".
Preset string `yaml:"preset" toml:"preset"`
// DisableTimestamp disables the timestamp from the "default" and "simple" formats.
DisableTimestamp bool `yaml:"disable_timestamp" toml:"disable_timestamp"`
// DisableComponent disables the component name from the "default" and "simple" formats.
DisableComponent bool `yaml:"disable_component" toml:"disable_component"`
// StructuredToStderr controls when structured logs are sent to stderr.
// Can be "auto" (default), "always", or "never".
StructuredToStderr string `yaml:"structured_to_stderr" toml:"structured_to_stderr"`
}
FormatConfig controls the log output format.
type LogEntry ¶
type LogEntry struct {
// contains filtered or unexported fields
}
LogEntry accumulates options before writing to both outputs. Use the chainable methods to configure the entry, then call Log(ctx) to execute.
func (*LogEntry) Emit ¶
func (e *LogEntry) Emit()
Emit logs the message without job context. Output routes to structured logging (workspace.log) and pretty output via GetGlobalOutput(). Use this for CLI commands and utility code that runs outside job execution.
For job execution code where you want output in job.log, use Log(ctx).
func (*LogEntry) Err ¶
Err attaches an error (chainable). The error message is added to structured output as the "error" field.
func (*LogEntry) Field ¶
Field adds a structured field (chainable). Fields appear in structured logs but not in pretty output unless included in .Pretty().
func (*LogEntry) Icon ¶
Icon overrides the default icon (chainable). Use theme.Icon* constants for consistent styling.
func (*LogEntry) Log ¶
Log executes the log entry, writing to both outputs based on configuration. This is the terminal method that must be called for the log to be written.
func (*LogEntry) Pretty ¶
Pretty sets a custom lipgloss-styled string for CLI/TUI output (chainable). The msg from Info/Warn/etc. is used for structured logs (clean, no ANSI). The Pretty string is used for user-facing display (fully styled).
Example:
ulog.Info("API call completed").
Field("status", 201).
Pretty(theme.IconSuccess + " " + theme.DefaultTheme.Success.Render("201 Created")).
Log(ctx)
func (*LogEntry) PrettyOnly ¶
PrettyOnly skips structured output (chainable). Use this for messages that should only appear in user-facing output.
func (*LogEntry) StructuredOnly ¶
StructuredOnly skips pretty output (chainable). Use this for detailed audit logging that shouldn't clutter the UI.
type OverrideOptions ¶
type OverrideOptions struct {
ShowAll bool
ShowOnly []string // For --component
AlsoShow []string // For --also-show
IgnoreHide []string // For --ignore-hide
}
OverrideOptions holds runtime filter settings from CLI flags.
type PrettyLogger ¶
type PrettyLogger struct {
// contains filtered or unexported fields
}
PrettyLogger provides pretty formatted console output
func NewPrettyLogger ¶
func NewPrettyLogger() *PrettyLogger
NewPrettyLogger creates a pretty logger wrapper
func (*PrettyLogger) BlankCtx ¶
func (p *PrettyLogger) BlankCtx(ctx context.Context)
BlankCtx prints a blank line to the writer from the context.
func (*PrettyLogger) Box ¶
func (p *PrettyLogger) Box(title, content string)
Box prints content in a styled box
func (*PrettyLogger) BoxCtx ¶
func (p *PrettyLogger) BoxCtx(ctx context.Context, title, content string)
BoxCtx prints content in a styled box to the writer from the context.
func (*PrettyLogger) Code ¶
func (p *PrettyLogger) Code(content string)
Code logs code or command output
func (*PrettyLogger) CodeCtx ¶
func (p *PrettyLogger) CodeCtx(ctx context.Context, content string)
CodeCtx logs code or command output to the writer from the context.
func (*PrettyLogger) DividerCtx ¶
func (p *PrettyLogger) DividerCtx(ctx context.Context)
DividerCtx prints a visual divider to the writer from the context.
func (*PrettyLogger) ErrorPretty ¶
func (p *PrettyLogger) ErrorPretty(message string, err error)
ErrorPretty logs an error with pretty formatting
func (*PrettyLogger) ErrorPrettyCtx ¶
func (p *PrettyLogger) ErrorPrettyCtx(ctx context.Context, message string, err error)
ErrorPrettyCtx logs an error with pretty formatting to the writer from the context.
func (*PrettyLogger) Field ¶
func (p *PrettyLogger) Field(key string, value interface{})
Field logs a key-value pair with pretty formatting
func (*PrettyLogger) FieldCtx ¶
func (p *PrettyLogger) FieldCtx(ctx context.Context, key string, value interface{})
FieldCtx logs a key-value pair with pretty formatting to the writer from the context.
func (*PrettyLogger) InfoPretty ¶
func (p *PrettyLogger) InfoPretty(message string)
InfoPretty logs an info message with pretty formatting
func (*PrettyLogger) InfoPrettyCtx ¶
func (p *PrettyLogger) InfoPrettyCtx(ctx context.Context, message string)
InfoPrettyCtx logs an info message with pretty formatting to the writer from the context.
func (*PrettyLogger) KeyValues ¶
func (p *PrettyLogger) KeyValues(pairs map[string]interface{})
KeyValue logs multiple key-value pairs
func (*PrettyLogger) KeyValuesCtx ¶
func (p *PrettyLogger) KeyValuesCtx(ctx context.Context, pairs map[string]interface{})
KeyValuesCtx logs multiple key-value pairs to the writer from the context.
func (*PrettyLogger) ListCtx ¶
func (p *PrettyLogger) ListCtx(ctx context.Context, items []string)
ListCtx logs a list of items to the writer from the context.
func (*PrettyLogger) Path ¶
func (p *PrettyLogger) Path(label string, path string)
Path logs a file path with special formatting
func (*PrettyLogger) PathCtx ¶
func (p *PrettyLogger) PathCtx(ctx context.Context, label string, path string)
PathCtx logs a file path with special formatting to the writer from the context.
func (*PrettyLogger) Progress ¶
func (p *PrettyLogger) Progress(message string)
Progress logs a progress message
func (*PrettyLogger) ProgressCtx ¶
func (p *PrettyLogger) ProgressCtx(ctx context.Context, message string)
ProgressCtx logs a progress message to the writer from the context.
func (*PrettyLogger) Section ¶
func (p *PrettyLogger) Section(title string)
Section prints a section header with the Grove theme
func (*PrettyLogger) SectionCtx ¶
func (p *PrettyLogger) SectionCtx(ctx context.Context, title string)
SectionCtx prints a section header with the Grove theme to the writer from the context.
func (*PrettyLogger) Status ¶
func (p *PrettyLogger) Status(status, message string)
Status logs a status with an appropriate icon
func (*PrettyLogger) StatusCtx ¶
func (p *PrettyLogger) StatusCtx(ctx context.Context, status, message string)
StatusCtx logs a status with an appropriate icon to the writer from the context.
func (*PrettyLogger) Success ¶
func (p *PrettyLogger) Success(message string)
Success logs a success message with a checkmark
func (*PrettyLogger) SuccessCtx ¶
func (p *PrettyLogger) SuccessCtx(ctx context.Context, message string)
SuccessCtx logs a success message to the writer from the context.
func (*PrettyLogger) WarnPretty ¶
func (p *PrettyLogger) WarnPretty(message string)
WarnPretty logs a warning with pretty formatting
func (*PrettyLogger) WarnPrettyCtx ¶
func (p *PrettyLogger) WarnPrettyCtx(ctx context.Context, message string)
WarnPrettyCtx logs a warning with pretty formatting to the writer from the context.
func (*PrettyLogger) WithWriter ¶
func (p *PrettyLogger) WithWriter(w io.Writer) *PrettyLogger
WithWriter sets a custom writer for pretty output
type PrettyStyles ¶
type PrettyStyles struct {
Success lipgloss.Style
Info lipgloss.Style
Warning lipgloss.Style
Error lipgloss.Style
Icon lipgloss.Style
Key lipgloss.Style
Value lipgloss.Style
Path lipgloss.Style
Code lipgloss.Style
Component lipgloss.Style
}
PrettyStyles contains lipgloss styles for different log types
func DefaultPrettyStyles ¶
func DefaultPrettyStyles() PrettyStyles
DefaultPrettyStyles returns the default styling for pretty logs using Grove theme
type TextFormatter ¶
type TextFormatter struct {
Config FormatConfig
}
TextFormatter is a custom logrus formatter.
type UnifiedLogger ¶
type UnifiedLogger struct {
// contains filtered or unexported fields
}
UnifiedLogger creates log entries that write to both pretty and structured outputs. It provides a builder pattern API for creating log messages that are rendered both as user-facing styled output and as structured audit logs.
func NewUnifiedLogger ¶
func NewUnifiedLogger(component string) *UnifiedLogger
NewUnifiedLogger creates a new unified logger for a specific component. The component name is used for structured log filtering and identification.
func (*UnifiedLogger) Component ¶
func (u *UnifiedLogger) Component() string
Component returns the component name for this logger.
func (*UnifiedLogger) Debug ¶
func (u *UnifiedLogger) Debug(msg string) *LogEntry
Debug returns a LogEntry at DEBUG level. Debug messages are hidden in pretty output by default (shown with --verbose or GROVE_LOG_LEVEL=debug).
func (*UnifiedLogger) Error ¶
func (u *UnifiedLogger) Error(msg string) *LogEntry
Error returns a LogEntry at ERROR level with IconError.
func (*UnifiedLogger) Info ¶
func (u *UnifiedLogger) Info(msg string) *LogEntry
Info returns a LogEntry at INFO level.
func (*UnifiedLogger) Progress ¶
func (u *UnifiedLogger) Progress(msg string) *LogEntry
Progress returns a LogEntry with IconRunning pre-set. Progress messages indicate in-progress operations.
func (*UnifiedLogger) Status ¶
func (u *UnifiedLogger) Status(msg string) *LogEntry
Status returns a LogEntry with IconInfo pre-set. Status messages provide informational updates.
func (*UnifiedLogger) Success ¶
func (u *UnifiedLogger) Success(msg string) *LogEntry
Success returns a LogEntry with IconSuccess pre-set. Success messages are logged at INFO level with status=success in structured output.
func (*UnifiedLogger) Warn ¶
func (u *UnifiedLogger) Warn(msg string) *LogEntry
Warn returns a LogEntry at WARN level with IconWarning.
func (*UnifiedLogger) WithPretty ¶
func (u *UnifiedLogger) WithPretty() *PrettyLogger
WithPretty returns the underlying PrettyLogger for direct pretty logging. Use this when you need to bypass the unified pattern for specific cases.
func (*UnifiedLogger) WithStructured ¶
func (u *UnifiedLogger) WithStructured() *logrus.Entry
WithStructured returns the underlying logrus entry for direct structured logging. Use this when you need to bypass the unified pattern for specific cases.
type VersionFields ¶
type VersionFields struct {
Branch string `json:"branch" verbosity:"3"`
Commit string `json:"commit" verbosity:"3"`
Binary string `json:"binary" verbosity:"3"`
Version string `json:"version" verbosity:"0"`
Platform string `json:"platform" verbosity:"3"`
GoVersion string `json:"goVersion" verbosity:"3"`
BuildDate string `json:"buildDate" verbosity:"1"`
Compiler string `json:"compiler" verbosity:"3"`
}
VersionFields represents the fields logged when a Grove binary starts
type VisibilityReason ¶
type VisibilityReason string
VisibilityReason provides a clear reason for a filtering decision.
const ( // ReasonVisibleDefault is for components visible because no rules hid them. ReasonVisibleDefault VisibilityReason = "visible_default" // ReasonVisibleByShow is for components visible due to a 'show' rule. ReasonVisibleByShow VisibilityReason = "visible_by_show" // ReasonVisibleByOnly is for components visible due to an 'only' whitelist rule. ReasonVisibleByOnly VisibilityReason = "visible_by_only" // ReasonVisibleByProject is for components visible because they are the current project. ReasonVisibleByProject VisibilityReason = "visible_by_project" // ReasonHiddenByHide is for components hidden by a 'hide' rule. ReasonHiddenByHide VisibilityReason = "hidden_by_hide" // ReasonHiddenByOnly is for components hidden by an 'only' whitelist. ReasonHiddenByOnly VisibilityReason = "hidden_by_only" // ReasonHiddenByDefault is for components hidden by the default 'grove-ecosystem' hide rule. ReasonHiddenByDefault VisibilityReason = "hidden_by_default" // ReasonVisibleByOverrideShowAll is for components visible due to --show-all override. ReasonVisibleByOverrideShowAll VisibilityReason = "visible_by_override_show_all" // ReasonVisibleByOverrideShowOnly is for components visible due to --component override. ReasonVisibleByOverrideShowOnly VisibilityReason = "visible_by_override_show_only" // ReasonVisibleByOverrideAlsoShow is for components visible due to --also-show override. ReasonVisibleByOverrideAlsoShow VisibilityReason = "visible_by_override_also_show" // ReasonVisibleByOverrideIgnore is for components visible due to --ignore-hide override. ReasonVisibleByOverrideIgnore VisibilityReason = "visible_by_override_ignore_hide" // ReasonHiddenByOverrideShowOnly is for components hidden by --component override. ReasonHiddenByOverrideShowOnly VisibilityReason = "hidden_by_override_show_only" )
type VisibilityResult ¶
type VisibilityResult struct {
Visible bool
Reason VisibilityReason
Rule []string // The config rule that was matched, e.g., ["grove-ecosystem"]
}
VisibilityResult holds the outcome of a component visibility check.
func GetComponentVisibility ¶
func GetComponentVisibility(component string, cfg *Config, overrides *OverrideOptions) VisibilityResult
GetComponentVisibility determines if a component's logs should be visible based on a hierarchy of rules.