Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A LoggerAdapter interface for integration with other logging packages #66

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ Implemented Jobs
- CurlJob
- FunctionJob

Logger interface. Any type that implements it can be used to log messages.
```go
type LoggerAdapter interface {
Log(msg string)
}
```
Implemented LoggerAdapter
- StdoutLogger

## Cron expression format

| Field Name | Mandatory | Allowed Values | Allowed Special Characters |
Expand Down
35 changes: 35 additions & 0 deletions examples/custom_log_adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"context"
"fmt"
"github.com/reugn/go-quartz/quartz"
"sync"
"time"
)

type CustomLogger struct{}

func (c *CustomLogger) Log(msg string) {
fmt.Printf("[CUSTOM LOGGER] %s", msg)
}

func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
wg := new(sync.WaitGroup)
wg.Add(1)

go func(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
sched := quartz.NewStdSchedulerWithOptions(quartz.StdSchedulerOptions{}, &CustomLogger{})
sched.Start(ctx)
sched.ScheduleJob(ctx, quartz.NewFunctionJob[int](func(ctx context.Context) (int, error) {
return 12, nil
}), quartz.NewRunOnceTrigger(time.Second))

time.Sleep(time.Second * 2)
}(ctx, wg)

wg.Wait()
}
16 changes: 16 additions & 0 deletions quartz/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package quartz

import (
"log"
)

type LoggerAdapter interface {
Log(msg string)
}

type StdoutLogger struct {
}

func (s *StdoutLogger) Log(msg string) {
log.Println(msg)
}
23 changes: 23 additions & 0 deletions quartz/log_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package quartz_test

import (
"bytes"
)

type BufferedLogger struct {
buffer *bytes.Buffer
}

func (b *BufferedLogger) Log(msg string) {
b.buffer.WriteString(msg + "\n")
}

func (b *BufferedLogger) GetContents() string {
return b.buffer.String()
}

func NewBufferedLogger() *BufferedLogger {
return &BufferedLogger{
buffer: new(bytes.Buffer),
}
}
22 changes: 14 additions & 8 deletions quartz/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"container/heap"
"context"
"errors"
"log"
"fmt"
"sync"
"time"
)
Expand Down Expand Up @@ -64,6 +64,7 @@ type StdScheduler struct {
dispatch chan *item
started bool
opts StdSchedulerOptions
logger LoggerAdapter
}

type StdSchedulerOptions struct {
Expand Down Expand Up @@ -102,18 +103,23 @@ var _ Scheduler = (*StdScheduler)(nil)
func NewStdScheduler() Scheduler {
return NewStdSchedulerWithOptions(StdSchedulerOptions{
OutdatedThreshold: 100 * time.Millisecond,
})
}, nil)
}

// NewStdSchedulerWithOptions returns a new StdScheduler configured as specified.
func NewStdSchedulerWithOptions(opts StdSchedulerOptions) *StdScheduler {
func NewStdSchedulerWithOptions(opts StdSchedulerOptions, logger LoggerAdapter) *StdScheduler {
if nil == logger {
logger = &StdoutLogger{}
}

return &StdScheduler{
queue: &priorityQueue{},
wg: &sync.WaitGroup{},
interrupt: make(chan struct{}, 1),
feeder: make(chan *item),
dispatch: make(chan *item),
opts: opts,
logger: logger,
}
}

Expand Down Expand Up @@ -244,7 +250,7 @@ func (sched *StdScheduler) Stop() {
return
}

log.Printf("Closing the StdScheduler.")
sched.logger.Log("Closing the StdScheduler.")
sched.cancel()
sched.started = false
}
Expand All @@ -256,7 +262,7 @@ func (sched *StdScheduler) startExecutionLoop(ctx context.Context) {
select {
case <-sched.interrupt:
case <-ctx.Done():
log.Printf("Exit the empty execution loop.")
sched.logger.Log("Exit the empty execution loop.")
return
}
} else {
Expand All @@ -269,7 +275,7 @@ func (sched *StdScheduler) startExecutionLoop(ctx context.Context) {
t.Stop()

case <-ctx.Done():
log.Printf("Exit the execution loop.")
sched.logger.Log("Exit the execution loop.")
t.Stop()
return
}
Expand Down Expand Up @@ -354,7 +360,7 @@ func (sched *StdScheduler) executeAndReschedule(ctx context.Context) {
// reschedule the Job
nextRunTime, err := it.Trigger.NextFireTime(it.priority)
if err != nil {
log.Printf("The Job '%s' got out the execution loop: %q", it.Job.Description(), err.Error())
sched.logger.Log(fmt.Sprintf("The Job '%s' got out the execution loop: %q", it.Job.Description(), err.Error()))
return
}
it.priority = nextRunTime
Expand All @@ -377,7 +383,7 @@ func (sched *StdScheduler) startFeedReader(ctx context.Context) {
sched.reset(ctx)
}()
case <-ctx.Done():
log.Printf("Exit the feed reader.")
sched.logger.Log("Exit the feed reader.")
return
}
}
Expand Down
21 changes: 20 additions & 1 deletion quartz/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"net/http"
"runtime"
"strings"
"sync/atomic"
"testing"
"time"
Expand Down Expand Up @@ -89,7 +90,7 @@ func TestSchedulerBlockingSemantics(t *testing.T) {

opts.OutdatedThreshold = 10 * time.Millisecond

sched := quartz.NewStdSchedulerWithOptions(opts)
sched := quartz.NewStdSchedulerWithOptions(opts, nil)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
sched.Start(ctx)
Expand Down Expand Up @@ -259,3 +260,21 @@ func TestSchedulerCancel(t *testing.T) {
})
}
}

func TestLogger(t *testing.T) {
ctx := context.Background()
logger := NewBufferedLogger()
sched := quartz.NewStdSchedulerWithOptions(quartz.StdSchedulerOptions{}, logger)
sched.Start(ctx)
sched.Stop()

content := logger.GetContents()

if len(content) == 0 {
t.Fatal("The log buffer is empty")
}

if !strings.Contains(content, "Closing the StdScheduler") {
t.Fatal(`The buffer not contains a string "Closing the StdScheduler""`)
}
}