Custom Log Writer in Go
Implementing the io.Writer interface in Go is a fundamental exercise in understanding interfaces and abstracting I/O operations. This challenge asks you to create a custom log writer that appends log messages to a provided string buffer, optionally prefixing each message with a timestamp. This is useful for building flexible logging systems that can easily be adapted to different output destinations.
Problem Description
You are tasked with creating a TimestampedLogWriter struct that implements the io.Writer interface. This struct should have a buffer field of type *strings.Builder and an optional timestampPrefix field of type string. The Write method of your custom writer should:
- If
timestampPrefixis set, prepend it to the inputp(byte slice). - Append the (potentially prefixed)
pto thebuffer.
The strings.Builder is used for efficient string concatenation. Your implementation should handle empty input gracefully.
Examples
Example 1:
Input:
buffer := &strings.Builder{}
writer := TimestampedLogWriter{buffer: buffer, timestampPrefix: "[TIMESTAMP]"}
writer.Write([]byte("Hello, world!"))
writer.Write([]byte(" Another log message."))
Output:
buffer.String() == "[TIMESTAMP]Hello, world!\n Another log message.\n"
Explanation: The messages are appended to the buffer with the timestamp prefix and a newline character.
Example 2:
Input:
buffer := &strings.Builder{}
writer := TimestampedLogWriter{buffer: buffer} // No timestamp prefix
writer.Write([]byte("Simple message."))
Output:
buffer.String() == "Simple message.\n"
Explanation: The message is appended to the buffer without a prefix and a newline character.
Example 3: (Edge Case - Empty Input)
Input:
buffer := &strings.Builder{}
writer := TimestampedLogWriter{buffer: buffer, timestampPrefix: "[TIMESTAMP]"}
writer.Write([]byte(""))
Output:
buffer.String() == "[TIMESTAMP]\n"
Explanation: Even an empty byte slice should result in a newline character being appended.
Constraints
- The
timestampPrefixcan be any string, including an empty string. - The
Writemethod should always append a newline character (\n) after each message. - The
bufferfield should be a pointer to astrings.Builder. - The
Writemethod should handle any byte slice input.
Notes
- Remember that
io.Writeris an interface, so you need to implement theWritemethod with the correct signature:(w io.Writer) Write(p []byte) (n int, err error). - The
strings.Builderis designed for efficient string concatenation. Avoid using+for string concatenation within theWritemethod, as this can be less performant. - Consider how you will handle the return values of the
Writemethod (n int, err error). For this challenge, you can simply returnlen(p), nil.
import (
"strings"
)
type TimestampedLogWriter struct {
buffer *strings.Builder
timestampPrefix string
}
func (w *TimestampedLogWriter) Write(p []byte) (n int, err error) {
// Your code here
}