Skip to content

Commit 72abcbe

Browse files
authored
Merge pull request #35 from cschleiden/logging
Add simple logging implementation
2 parents 7a021b5 + 1460ea0 commit 72abcbe

File tree

41 files changed

+488
-169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+488
-169
lines changed

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ The Sqlite backend implementation supports two different modes, in-memory and on
141141
b := mysql.NewMysqlBackend("localhost", 3306, "root", "SqlPassw0rd", "simple")
142142
```
143143

144+
144145
## Guide
145146

146147
### Registering workflows
@@ -454,6 +455,43 @@ func TestWorkflow(t *testing.T) {
454455
- Timers are automatically fired by advancing a mock workflow clock that is used for testing workflows
455456
- You can register callbacks to fire at specific times (in mock-clock time). Callbacks can send signals, cancel workflows etc.
456457

458+
### Logging
459+
460+
For logging, you can pass a type to the backend via the `WithLogger` option to set a custom logger. The type has to implement this simple interface:
461+
462+
```go
463+
type Logger interface {
464+
Debug(msg string, fields ...interface{})
465+
Warn(msg string, fields ...interface{})
466+
Error(msg string, fields ...interface{})
467+
Panic(msg string, fields ...interface{})
468+
469+
With(fields ...interface{}) Logger
470+
}
471+
```
472+
473+
If you don't pass a logger, a very simple, unoptimized default logger is used. For production use it is strongly recommended to pass another logger.
474+
475+
#### Workflows
476+
477+
For logging in workflows, you can get a logger using
478+
479+
```go
480+
logger := workflow.Logger(ctx)
481+
```
482+
483+
The returned `logger` implements the `Logger` interface, and already has the workflow instance and execution IDs set as default fields.
484+
485+
#### Activities
486+
487+
For logging in activities, you can get a logger using
488+
489+
```go
490+
logger := activity.Logger(ctx)
491+
```
492+
493+
The returned `logger` implements the `Logger` interface, and already has the id of the activity, and the workflow instance and execution IDs set as default fields.
494+
457495
## Versioning
458496
459497
For now, I've intentionally left our versioning. Cadence, Temporal, and DTFx all support the concept of versions for workflows as well as activities. This is mostly required when you make changes to workflows and need to keep backwards compatibility with workflows that are being executed at the time of the upgrade.

activity/logger.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package activity
2+
3+
import (
4+
"context"
5+
6+
"github.com/cschleiden/go-workflows/internal/activity"
7+
"github.com/cschleiden/go-workflows/log"
8+
)
9+
10+
// Logger returns a logger with the workflow instance this activity is executed for set as default fields
11+
func Logger(ctx context.Context) log.Logger {
12+
return activity.GetActivityState(ctx).Logger
13+
}

backend/backend.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
core "github.com/cschleiden/go-workflows/internal/core"
88
"github.com/cschleiden/go-workflows/internal/history"
99
"github.com/cschleiden/go-workflows/internal/task"
10+
"github.com/cschleiden/go-workflows/log"
1011
"github.com/cschleiden/go-workflows/workflow"
1112
)
1213

@@ -59,4 +60,7 @@ type Backend interface {
5960

6061
// ExtendActivityTask extends the lock of an activity task
6162
ExtendActivityTask(ctx context.Context, activityID string) error
63+
64+
// Logger returns the configured logger for the backend
65+
Logger() log.Logger
6266
}

backend/mock_Backend.go

Lines changed: 23 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/mysql/mysql.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/cschleiden/go-workflows/internal/core"
1313
"github.com/cschleiden/go-workflows/internal/history"
1414
"github.com/cschleiden/go-workflows/internal/task"
15+
"github.com/cschleiden/go-workflows/log"
1516
"github.com/cschleiden/go-workflows/workflow"
1617
_ "github.com/go-sql-driver/mysql"
1718
"github.com/google/uuid"
@@ -83,6 +84,10 @@ func (b *mysqlBackend) CreateWorkflowInstance(ctx context.Context, m history.Wor
8384
return nil
8485
}
8586

87+
func (b *mysqlBackend) Logger() log.Logger {
88+
return b.options.Logger
89+
}
90+
8691
func (b *mysqlBackend) CancelWorkflowInstance(ctx context.Context, instance *workflow.Instance, event *history.Event) error {
8792
tx, err := b.db.BeginTx(ctx, nil)
8893
if err != nil {

backend/options.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
package backend
22

3-
import "time"
3+
import (
4+
"time"
5+
6+
"github.com/cschleiden/go-workflows/internal/logger"
7+
"github.com/cschleiden/go-workflows/log"
8+
)
49

510
type Options struct {
11+
Logger log.Logger
12+
613
StickyTimeout time.Duration
714

815
WorkflowLockTimeout time.Duration
@@ -24,12 +31,22 @@ func WithStickyTimeout(timeout time.Duration) BackendOption {
2431
}
2532
}
2633

34+
func WithLogger(logger log.Logger) BackendOption {
35+
return func(o *Options) {
36+
o.Logger = logger
37+
}
38+
}
39+
2740
func ApplyOptions(opts ...BackendOption) Options {
2841
options := DefaultOptions
2942

3043
for _, opt := range opts {
3144
opt(&options)
3245
}
3346

47+
if options.Logger == nil {
48+
options.Logger = logger.NewDefaultLogger()
49+
}
50+
3451
return options
3552
}

backend/redis/instance.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ func (rb *redisBackend) CreateWorkflowInstance(ctx context.Context, event histor
4444
}
4545
}
4646

47+
rb.options.Logger.Debug("Created new workflow instance")
48+
4749
return nil
4850
}
4951

backend/redis/redis.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/cschleiden/go-workflows/backend"
77
"github.com/cschleiden/go-workflows/backend/redis/taskqueue"
88
"github.com/cschleiden/go-workflows/internal/history"
9+
"github.com/cschleiden/go-workflows/log"
910
"github.com/go-redis/redis/v8"
1011
"github.com/pkg/errors"
1112
)
@@ -57,7 +58,7 @@ func NewRedisBackend(address, username, password string, db int, opts ...RedisBa
5758

5859
// Default options
5960
options := &RedisOptions{
60-
Options: backend.DefaultOptions,
61+
Options: backend.ApplyOptions(),
6162
BlockTimeout: time.Second * 5,
6263
}
6364

@@ -94,3 +95,7 @@ type activityData struct {
9495
type workflowTaskData struct {
9596
LastPendingEventMessageID string `json:"last_pending_event_message_id,omitempty"`
9697
}
98+
99+
func (rb *redisBackend) Logger() log.Logger {
100+
return rb.options.Logger
101+
}

backend/redis/redis_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import (
1212
)
1313

1414
func Test_RedisBackend(t *testing.T) {
15+
if testing.Short() {
16+
t.Skip()
17+
}
18+
1519
test.BackendTest(t, func() backend.Backend {
1620
address := "localhost:6379"
1721
user := ""

backend/sqlite/sqlite.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/cschleiden/go-workflows/internal/core"
1313
"github.com/cschleiden/go-workflows/internal/history"
1414
"github.com/cschleiden/go-workflows/internal/task"
15+
"github.com/cschleiden/go-workflows/log"
1516
"github.com/cschleiden/go-workflows/workflow"
1617
"github.com/google/uuid"
1718
"github.com/pkg/errors"
@@ -58,6 +59,10 @@ type sqliteBackend struct {
5859
options backend.Options
5960
}
6061

62+
func (sb *sqliteBackend) Logger() log.Logger {
63+
return sb.options.Logger
64+
}
65+
6166
func (sb *sqliteBackend) CreateWorkflowInstance(ctx context.Context, m history.WorkflowEvent) error {
6267
tx, err := sb.db.BeginTx(ctx, nil)
6368
if err != nil {

0 commit comments

Comments
 (0)