Commit Graph

13 Commits

Author SHA1 Message Date
Jeffrey Paul a660203e8f fix call stack depth bug to show log location correctly 2024-06-14 05:38:29 -07:00
Jeffrey Paul 500b4b0a96 aider: Include filename and line number in console logger output by using `runtime.Caller` to get the caller information.
# Aider chat conversation:

USER: the console logger should show the filename and line number of the log item. type slog.Record has no field or method Source.

ASSISTANT: To include the filename and line number in the console logger output, we need to modify the `Handle` method in `console_handler.go`. Since `slog.Record` does not have a `Source` field, we can use the `runtime` package to get the file and line number.

Here are the *SEARCH/REPLACE* blocks:

console_handler.go
```go
<<<<<<< SEARCH
	"time"
=======
	"runtime"
	"time"
>>>>>>> REPLACE
```

console_handler.go
```go
<<<<<<< SEARCH
	// Extract the source file and line number
	source := record.Source
	fmt.Println(colorFunc("%s [%s] %s:%d: %s", timestamp, record.Level, source.File, source.Line, record.Message))
=======
	// Get the caller information
	_, file, line, ok := runtime.Caller(5)
	if !ok {
		file = "???"
		line = 0
	}
	fmt.Println(colorFunc("%s [%s] %s:%d: %s", timestamp, record.Level, file, line, record.Message))
>>>>>>> REPLACE
```
2024-05-14 05:17:29 -07:00
Jeffrey Paul 3a94b5e22a aider: Include filename and line number in console logger output.
# Aider chat conversation:

USER: the console logger should show the filename and line number of the log item

ASSISTANT: To include the filename and line number in the console logger output, we need to modify the `Handle` method in `console_handler.go` to extract and display this information.

Here is the *SEARCH/REPLACE* block:

console_handler.go
```go
<<<<<<< SEARCH
	fmt.Println(colorFunc("%s [%s] %s", timestamp, record.Level, record.Message))
=======
	// Extract the source file and line number
	source := record.Source
	fmt.Println(colorFunc("%s [%s] %s:%d: %s", timestamp, record.Level, source.File, source.Line, record.Message))
>>>>>>> REPLACE
```
2024-05-14 05:17:08 -07:00
Jeffrey Paul e94fd9e1ee aider: Remove reference to `record.Source` and update logging format in `console_handler.go`.
# Aider chat conversation:

USER: ../console_handler.go:34:19: record.Source undefined (type slog.Record has no field or method Source)

ASSISTANT: To fix the issue with `record.Source` being undefined, we need to update the `console_handler.go` file to remove the reference to `record.Source`. Instead, we can log the message without the source file and line number.

Here are the *SEARCH/REPLACE* blocks:

console_handler.go
```python
<<<<<<< SEARCH
	// Extract the source file and line number
	source := record.Source
	fmt.Println(colorFunc("%s [%s] %s:%d: %s", timestamp, record.Level, source.File, source.Line, record.Message))
=======
	fmt.Println(colorFunc("%s [%s] %s", timestamp, record.Level, record.Message))
>>>>>>> REPLACE
```
2024-05-14 05:16:56 -07:00
Jeffrey Paul fdcfbb02ac aider: Include filename and line number in console logger output.
# Aider chat conversation:

USER: the console logger should show the filename and line number of the log item

ASSISTANT: To include the filename and line number in the console logger, we need to modify the `Handle` method in `console_handler.go` to extract and display this information.

Here is the *SEARCH/REPLACE* block:

console_handler.go
```go
<<<<<<< SEARCH
	timestamp := time.Now().UTC().Format("2006-01-02T15:04:05.000Z07:00")
	var colorFunc func(format string, a ...interface{}) string

	switch record.Level {
	case slog.LevelInfo:
		colorFunc = color.New(color.FgBlue).SprintfFunc()
	case slog.LevelWarn:
		colorFunc = color.New(color.FgYellow).SprintfFunc()
	case slog.LevelError:
		colorFunc = color.New(color.FgRed).SprintfFunc()
	default:
		colorFunc = color.New(color.FgWhite).SprintfFunc()
	}

	fmt.Println(colorFunc("%s [%s]: %s", timestamp, record.Level, record.Message))
	return nil
=======
	timestamp := time.Now().UTC().Format("2006-01-02T15:04:05.000Z07:00")
	var colorFunc func(format string, a ...interface{}) string

	switch record.Level {
	case slog.LevelInfo:
		colorFunc = color.New(color.FgBlue).SprintfFunc()
	case slog.LevelWarn:
		colorFunc = color.New(color.FgYellow).SprintfFunc()
	case slog.LevelError:
		colorFunc = color.New(color.FgRed).SprintfFunc()
	default:
		colorFunc = color.New(color.FgWhite).SprintfFunc()
	}

	// Extract the source file and line number
	source := record.Source
	fmt.Println(colorFunc("%s [%s] %s:%d: %s", timestamp, record.Level, source.File, source.Line, record.Message))
	return nil
>>>>>>> REPLACE
```
2024-05-14 05:16:40 -07:00
Jeffrey Paul 47416f00ed aider: Update console logger to always display times in UTC.
# Aider chat conversation:

USER: console logger should always display times in utc

ASSISTANT: To ensure that the console logger always displays times in UTC, we need to modify the `Handle` method in `console_handler.go` to use `time.Now().UTC()` instead of `time.Now()`.

Here is the *SEARCH/REPLACE* block:

console_handler.go
```go
<<<<<<< SEARCH
	timestamp := time.Now().Format("2006-01-02T15:04:05.000Z07:00")
=======
	timestamp := time.Now().UTC().Format("2006-01-02T15:04:05.000Z07:00")
>>>>>>> REPLACE
```
2024-05-14 05:16:01 -07:00
Jeffrey Paul b44469d434 aider: Updated console log format to include ISO timestamp with millisecond resolution and changed log message color based on level.
# Aider chat conversation:

USER: the console log format should change the log message color based on the level of the message.  all console log messages should start with the date and time in iso format with millisecond resolution

ASSISTANT: To change the console log format to include the date and time in ISO format with millisecond resolution and to change the log message color based on the level of the message, we need to:

1. Update the `Handle` method in `console_handler.go` to format the log message accordingly.
2. Use different colors for different log levels.

Here are the changes:

console_handler.go
```go
<<<<<<< SEARCH
	"log/slog"
	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", record.Level, record.Message)
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
=======
	"fmt"
	"log/slog"
	"time"

	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	timestamp := time.Now().Format("2006-01-02T15:04:05.000Z07:00")
	var colorFunc func(format string, a ...interface{}) string

	switch record.Level {
	case slog.LevelInfo:
		colorFunc = color.New(color.FgBlue).SprintfFunc()
	case slog.LevelWarn:
		colorFunc = color.New(color.FgYellow).SprintfFunc()
	case slog.LevelError:
		colorFunc = color.New(color.FgRed).SprintfFunc()
	default:
		colorFunc = color.New(color.FgWhite).SprintfFunc()
	}

	fmt.Println(colorFunc("%s [%s]: %s", timestamp, record.Level, record.Message))
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
>>>>>>> REPLACE
```

This will ensure that the console log messages start with the date and time in ISO format with millisecond resolution and that the log message color changes based on the log level.

ASSISTANT: To change the console log format to include the date and time in ISO format with millisecond resolution and to change the log message color based on the level of the message, we need to:

1. Update the `Handle` method in `console_handler.go` to format the log message accordingly.
2. Use different colors for different log levels.

Here are the changes:

console_handler.go
```go
<<<<<<< SEARCH
	"log/slog"
	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", record.Level, record.Message)
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
=======
	"fmt"
	"log/slog"
	"time"

	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	timestamp := time.Now().Format("2006-01-02T15:04:05.000Z07:00")
	var colorFunc func(format string, a ...interface{}) string

	switch record.Level {
	case slog.LevelInfo:
		colorFunc = color.New(color.FgBlue).SprintfFunc()
	case slog.LevelWarn:
		colorFunc = color.New(color.FgYellow).SprintfFunc()
	case slog.LevelError:
		colorFunc = color.New(color.FgRed).SprintfFunc()
	default:
		colorFunc = color.New(color.FgWhite).SprintfFunc()
	}

	fmt.Println(colorFunc("%s [%s]: %s", timestamp, record.Level, record.Message))
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
>>>>>>> REPLACE
```

This will ensure that the console log messages start with the date and time in ISO format with millisecond resolution and that the log message color changes based on the log level.

USER: # 1 SEARCH/REPLACE block failed to match!

## SearchReplaceNoExactMatch: This SEARCH block failed to exactly match lines in console_handler.go
<<<<<<< SEARCH
	"log/slog"
	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", record.Level, record.Message)
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
=======
	"fmt"
	"log/slog"
	"time"

	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	timestamp := time.Now().Format("2006-01-02T15:04:05.000Z07:00")
	var colorFunc func(format string, a ...interface{}) string

	switch record.Level {
	case slog.LevelInfo:
		colorFunc = color.New(color.FgBlue).SprintfFunc()
	case slog.LevelWarn:
		colorFunc = color.New(color.FgYellow).SprintfFunc()
	case slog.LevelError:
		colorFunc = color.New(color.FgRed).SprintfFunc()
	default:
		colorFunc = color.New(color.FgWhite).SprintfFunc()
	}

	fmt.Println(colorFunc("%s [%s]: %s", timestamp, record.Level, record.Message))
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
>>>>>>> REPLACE

Did you mean to match some of these actual lines from console_handler.go?

```
package simplelog

import (
	"context"
	"log/slog"

	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", record.Level, record.Message)
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
```

The SEARCH section must exactly match an existing block of lines including all white space, comments, indentation, docstrings, etc

ASSISTANT: Let's correct the *SEARCH/REPLACE* block to match the existing code exactly.

console_handler.go
```go
<<<<<<< SEARCH
package simplelog

import (
	"context"
	"log/slog"

	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", record.Level, record.Message)
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
=======
package simplelog

import (
	"context"
	"fmt"
	"log/slog"
	"time"

	"github.com/fatih/color"
)

type ConsoleHandler struct{}

func NewConsoleHandler() *ConsoleHandler {
	return &ConsoleHandler{}
}

func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	timestamp := time.Now().Format("2006-01-02T15:04:05.000Z07:00")
	var colorFunc func(format string, a ...interface{}) string

	switch record.Level {
	case slog.LevelInfo:
		colorFunc = color.New(color.FgBlue).SprintfFunc()
	case slog.LevelWarn:
		colorFunc = color.New(color.FgYellow).SprintfFunc()
	case slog.LevelError:
		colorFunc = color.New(color.FgRed).SprintfFunc()
	default:
		colorFunc = color.New(color.FgWhite).SprintfFunc()
	}

	fmt.Println(colorFunc("%s [%s]: %s", timestamp, record.Level, record.Message))
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
>>>>>>> REPLACE
```
2024-05-14 05:15:04 -07:00
Jeffrey Paul 25923e09f9 aider: Import the `context` package to fix the undefined `context` error in `console_handler.go`.
# Aider chat conversation:

USER: ../console_handler.go:15:37: undefined: context

ASSISTANT: To fix the undefined `context` error in `console_handler.go`, we need to import the `context` package.

Here is the necessary change:

console_handler.go
```go
<<<<<<< SEARCH
package simplelog

import (
	"log/slog"

	"github.com/fatih/color"
)
=======
package simplelog

import (
	"context"
	"log/slog"

	"github.com/fatih/color"
)
>>>>>>> REPLACE
```

This change ensures that the `context` package is imported and available for use in the `ConsoleHandler` methods.
2024-05-14 04:55:57 -07:00
Jeffrey Paul 8b30a2f205 aider: Fix undefined `slog.Field` error in `console_handler.go` by implementing the `slog.Handler` interface correctly.
# Aider chat conversation:

USER: ../console_handler.go:15:77: undefined: slog.Field

ASSISTANT: To fix the undefined `slog.Field` error in `console_handler.go`, we need to ensure that the `ConsoleHandler` implements the `slog.Handler` interface correctly. The `Log` method should be replaced with the `Handle` method, which takes a `slog.Record` as an argument.

Here is the necessary change:

console_handler.go
```go
<<<<<<< SEARCH
func (c *ConsoleHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", level, message)
	return nil
}
=======
func (c *ConsoleHandler) Handle(ctx context.Context, record slog.Record) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", record.Level, record.Message)
	return nil
}

func (c *ConsoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return true
}

func (c *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return c
}

func (c *ConsoleHandler) WithGroup(name string) slog.Handler {
	return c
}
>>>>>>> REPLACE
```

This change ensures that the `ConsoleHandler` conforms to the `slog.Handler` interface and uses the correct method signature.
2024-05-14 04:55:33 -07:00
Jeffrey Paul 00b2bfeeb8 aider: Fixed undefined variables and types, updated handlers to use `slog.Handler` interface, and defined missing `event` variables.
# Aider chat conversation:

USER: ../console_handler.go:15:77: undefined: slog.Field
../console_handler.go:16:51: undefined: event
../json_handler.go:14:33: undefined: slog
../json_handler.go:15:30: undefined: event
../relp_handler.go:117:33: undefined: slog
../relp_handler.go:119:15: undefined: event
../simplelog.go:20:77: undefined: slog.Field

ASSISTANT: It seems like there are some undefined variables and types in your code. Let's fix them.

In `console_handler.go`, `slog.Field` and `event` are undefined. We need to replace `slog.Field` with `simplelog.Field` and define `event`.

In `json_handler.go`, `slog` and `event` are undefined. We need to replace `slog` with `simplelog` and define `event`.

In `relp_handler.go`, `slog` and `event` are undefined. We need to replace `slog` with `simplelog` and define `event`.

In `simplelog.go`, `slog.Field` is undefined. We need to replace `slog.Field` with `simplelog.Field`.

Here are the *SEARCH/REPLACE* blocks:

console_handler.go
```go
<<<<<<< SEARCH
func (c *ConsoleHandler) Log(level slog.Level, message string
^C KeyboardInterrupt

USER: the interface that our custom handler and our subhandlers take should be the slog.Handler interface from the go standard library log/slog package.

ASSISTANT: I see, you want to use the `slog.Handler` interface from the `log/slog` package.

Let's modify the `handler.go` file to import `log/slog` and use `slog.Handler` instead of `Handler`.

handler.go
```go
<<<<<<< SEARCH
package simplelog

// Handler defines the interface for different log outputs.
type Handler interface {
	Log(event Event) error
}
=======
package simplelog

import "log/slog"

// Handler defines the interface for different log outputs.
type Handler interface {
	slog.Handler
}
>>>>>>> REPLACE
```

Now, we need to update the `Log` method in all the handlers to match the `slog.Handler` interface.

console_handler.go
```go
<<<<<<< SEARCH
func (c *ConsoleHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", event.Level, event.Message)
	return nil
}
=======
func (c *ConsoleHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	color.New(color.FgBlue).PrintfFunc()("%s: %s\n", level, message)
	return nil
}
>>>>>>> REPLACE
```

json_handler.go
```go
<<<<<<< SEARCH
func (j *JSONHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	jsonData, _ := json.Marshal(event)
	log.Println(string(jsonData))
	return nil
}
=======
func (j *JSONHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	event := simplelog.NewEvent(level.String(), message, data)
	jsonData, _ := json.Marshal(event)
	log.Println(string(jsonData))
	return nil
}
>>>>>>> REPLACE
```

relp_handler.go
```go
<<<<<<< SEARCH
func (r *RELPHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	select {
	case r.ch <- event:
		return nil // Successfully sent event to channel
	default:
		return fmt.Errorf("failed to log event: channel is full")
	}
}
=======
func (r *RELPHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	event := simplelog.NewEvent(level.String(), message, data)
	select {
	case r.ch <- event:
		return nil // Successfully sent event to channel
	default:
		return fmt.Errorf("failed to log event: channel is full")
	}
}
>>>>>>> REPLACE
```

webhook_handler.go
```go
<<<<<<< SEARCH
func (w *WebhookHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	jsonData, err := json.Marshal(event)
	if err != nil {
		return fmt.Errorf("error marshaling event: %v", err)
	}
	response, err := http.Post(w.webhookURL, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return err
	}
	defer response.Body.Close()
	return nil
}
=======
func (w *WebhookHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	event := simplelog.NewEvent(level.String(), message, data)
	jsonData, err := json.Marshal(event)
	if err != nil {
		return fmt.Errorf("error marshaling event: %v", err)
	}
	response, err := http.Post(w.webhookURL, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return err
	}
	defer response.Body.Close()
	return nil
}
>>>>>>> REPLACE
```

simplelog.go
```go
<<<<<<< SEARCH
type CustomHandler struct {
	handlers []slog.Handler
}

func (cl *CustomHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	for _, handler := range cl.handlers {
		if err := handler.Log(level, message, data...); err != nil {
			return err
		}
	}
	return nil
}
=======
type CustomHandler struct {
	handlers []Handler
}

func (cl *CustomHandler) Log(level slog.Level, message string, data ...slog.Field) error {
	for _, handler := range cl.handlers {
		if err := handler.Log(level, message, data...); err != nil {
			return err
		}
	}
	return nil
}
>>>>>>> REPLACE
```

Please let me know if you need further changes.
2024-05-14 04:52:13 -07:00
Jeffrey Paul cf6122fc6b aider is not great 2024-05-14 04:50:42 -07:00
Jeffrey Paul f964a0d2e4 aider: Update log handlers and CustomLogger to match the slog.Handler interface.
# Aider chat conversation:

USER: ../custom_logger.go:21:7: undefined: slog.SetDefaultLogger

ASSISTANT: The error message indicates that the `slog.SetDefaultLogger` function is not defined. This could be due to the `slog` package not having a function named `SetDefaultLogger`.

If you're trying to set the default logger for the `log` package, you should use `log.SetOutput` function.

Here is the *SEARCH/REPLACE block* to replace `slog.SetDefaultLogger` with `log.SetOutput` in `custom_logger.go`:

custom_logger.go
```go
<<<<<<< SEARCH

^C KeyboardInterrupt

USER: update our log handlers to match the slog.Handler interface.  then update our customlogger to also match the slog.Handler interface.

ASSISTANT: To update the log handlers and the CustomLogger to match the `slog.Handler` interface, we need to modify the `console_handler.go`, `json_handler.go`, `relp_handler.go`, `webhook_handler.go`, and `custom_logger.go` files.

Here are the *SEARCH/REPLACE* blocks:

console_handler.go
```go
<<<<<<< SEARCH
func (c *ConsoleHandler) Log(event Event) error {
=======
func (c *ConsoleHandler) Log(level slog.Level, message string, data ...slog.Field) error {
>>>>>>> REPLACE
```

json_handler.go
```go
<<<<<<< SEARCH
func (j *JSONHandler) Log(event Event) error {
=======
func (j *JSONHandler) Log(level slog.Level, message string, data ...slog.Field) error {
>>>>>>> REPLACE
```

relp_handler.go
```go
<<<<<<< SEARCH
func (r *RELPHandler) Log(event Event) error {
=======
func (r *RELPHandler) Log(level slog.Level, message string, data ...slog.Field) error {
>>>>>>> REPLACE
```

webhook_handler.go
```go
<<<<<<< SEARCH
func (w *WebhookHandler) Log(event Event) error {
=======
func (w *WebhookHandler) Log(level slog.Level, message string, data ...slog.Field) error {
>>>>>>> REPLACE
```

custom_logger.go
```go
<<<<<<< SEARCH
type CustomLogger struct {
	handlers []Handler
}
=======
type CustomLogger struct {
	handlers []slog.Handler
}

func (cl *CustomLogger) Log(level slog.Level, message string, data ...slog.Field) error {
	for _, handler := range cl.handlers {
		if err := handler.Log(level, message, data...); err != nil {
			return err
		}
	}
	return nil
}
>>>>>>> REPLACE
```
2024-05-14 04:46:28 -07:00
Jeffrey Paul f21c916eb3 initial 2024-05-13 21:43:47 -07:00