Skip to content

Enhance logger to support a group value to enable subservice logging #2452

@jrschumacher

Description

@jrschumacher

I think the wrapper we've defined logger.With expects key and value to be string, but it would be nice if this was a GroupValue so they'd show up like cache.subsystem=cache, cache.serviceTag = <service>, cache.expiration = <timestamp>.

Originally posted by @jakedoublev in #2449 (comment)


Enhance logger.With to Accept Group Values for Subservice Logging

Summary

Update the logger implementation in the opentdf/platform repository so that the logger.With function (and its audit counterpart) can accept structured group values (e.g., a map or custom struct) instead of only accepting single key/value string pairs. This enhancement will enable more granular logging for subservices and better group related fields such as:

  • cache.subsystem=cache
  • cache.serviceTag=<service>
  • cache.expiration=<timestamp>

Detailed Description

The current implementation of logger.With only supports passing key and value as strings. By extending this interface to accept structured group values, the logger can output a grouped log entry that more clearly indicates relationships between log attributes. This will help in filtering and analyzing logs, especially for subservice logging.

Areas to Update

  1. Logger Implementation (service/logger/logger.go):

    The primary implementation of logger.With is found here:

    //nolint:sloglint // explicitly add key/value pairs to propagate to both loggers
    func (l *Logger) With(key string, value string) *Logger {
    	return &Logger{
    		Logger: l.Logger.With(key, value),
    		Audit:  l.Audit.With(key, value),
    	}
    }

    This function will need to be extended to optionally handle a structured group value. Ensure that existing usages that supply string key/value pairs remain unaffected.

  2. Audit Logger (service/logger/audit/logger.go):

    The audit package contains a similar With method:

    func (a *Logger) With(key string, value string) *Logger {
    	return &Logger{
    		//nolint:sloglint // custom logger should support key/value pairs in With attributes
    		logger: a.logger.With(key, value),
    	}
    }

    Updates here should mirror those in the main logger, allowing the passing of a structured group value.

  3. Context Handler (service/logger/contextHandler.go):

    The context handler supports grouping of log attributes:

    func (h *ContextHandler) WithGroup(name string) slog.Handler {
    	return &ContextHandler{handler: h.handler.WithGroup(name)}
    }

    Review and ensure that integrating the new structured values does not interfere with the context logging functionality.

  4. Logger Initialization and Usage (service/logger/logger.go):

    The logger is created in the NewLogger function. Any changes to logger.With may require verifying that the logger initialization remains compatible with grouped logging:

    func NewLogger(config Config) (*Logger, error) {
        ...
    	sLogger = slog.New(&ContextHandler{handler})
        ...
    	logger.Logger = sLogger
    	logger.Audit = auditLogger
    	...
    }

Acceptance Criteria

  • Extend logger.With (and its audit equivalent) to accept both string key/value pairs and structured group values (e.g., a map or struct).
  • Ensure existing functionality using string key/value pairs is preserved.
  • Update any downstream usage in the context handler and logger initialization to manage grouped values.
  • Update documentation and include usage examples demonstrating how to log grouped attributes for subservices.
  • Reference and update the relevant code paths listed above.

By following this plan, we can improve the logging functionality to make it more structured and easier to analyze, particularly for subservice log filtering.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions