Hone logo
Hone
Problems

Go Error Tracking with Structured Logging

In modern software development, robust error tracking is crucial for identifying, diagnosing, and resolving issues efficiently. This challenge focuses on implementing a basic error tracking system in Go that leverages structured logging to provide context and facilitate debugging. You will create a system that captures errors, enriches them with relevant information, and logs them in a standardized, machine-readable format.

Problem Description

Your task is to build a Go package that provides a centralized mechanism for tracking and logging errors. This system should:

  1. Capture Errors: Allow functions to report errors to a central tracker.
  2. Enrich Errors: Attach contextual information to errors before they are logged. This context could include the function name, user ID, request ID, or any other relevant details that help pinpoint the source of the error.
  3. Structured Logging: Log the enriched errors in a structured format (e.g., JSON) so they can be easily parsed by logging aggregation tools.
  4. Customizable Output: Provide flexibility in how errors are handled and logged.

Key Requirements:

  • Implement an ErrorTracker interface or struct that manages error tracking.
  • Create a function to register an error with contextual data.
  • The logged output for each error must be structured and include at least:
    • Timestamp
    • Error message
    • Severity level (e.g., "ERROR", "WARNING")
    • Contextual key-value pairs
  • The system should be thread-safe.

Expected Behavior:

When an error occurs, it should be sent to the ErrorTracker. The tracker will then format this error along with the provided context and log it. Subsequent calls to the tracking function with different errors or contexts should result in distinct log entries.

Edge Cases:

  • Handling nil errors gracefully.
  • Ensuring thread safety when multiple goroutines report errors concurrently.
  • What happens if the context provided is empty?

Examples

Example 1: Basic Error Tracking

Input:
error: fmt.Errorf("failed to connect to database")
context: {"component": "database", "operation": "connect"}

Output (example, actual format may vary based on implementation):
{"timestamp": "2023-10-27T10:00:00Z", "level": "ERROR", "message": "failed to connect to database", "component": "database", "operation": "connect"}

Explanation: A simple error is tracked with two pieces of context. The output is a JSON object containing the timestamp, error level, the error message, and the provided context.

Example 2: Tracking with More Context

Input:
error: errors.New("user not found")
context: {"userID": "abc-123", "requestID": "req-xyz-789", "handler": "getUser"}

Output (example):
{"timestamp": "2023-10-27T10:05:00Z", "level": "ERROR", "message": "user not found", "userID": "abc-123", "requestID": "req-xyz-789", "handler": "getUser"}

Explanation: Another error is tracked, this time with more specific context related to a user request.

Example 3: Handling nil Error

Input:
error: nil
context: {"info": "operation completed successfully"}

Output:
(No error is logged, but successful operations *could* be logged with a different level like "INFO" if the tracker were extended)

Explanation: If a nil error is passed, no error-specific log entry should be generated. The system should simply do nothing or, if designed for it, log a non-error event. For this challenge, we'll focus on error logging, so nil should be a no-op for error tracking.

Constraints

  • The solution must be written in Go.
  • The core error tracking logic should be encapsulated within a Go package.
  • The structured log output should be easily parsable (JSON is a good format to aim for).
  • The system must be thread-safe to handle concurrent error reporting.
  • The solution should not rely on external logging libraries beyond the standard library (e.g., log, encoding/json).

Notes

  • Consider how you will represent the "context" of an error. A map[string]interface{} is a flexible choice.
  • Think about how to add a timestamp to each log entry.
  • The encoding/json package will be very useful for creating structured output.
  • For thread safety, look into using sync.Mutex or sync.RWMutex.
  • Your solution should be easily extensible to support different logging destinations or more advanced error enrichment in the future.
  • The primary goal is to demonstrate a robust way to capture and log errors with context in Go.
Loading editor...
go