Skip to content

Commit

Permalink
Add WithDebug option
Browse files Browse the repository at this point in the history
  • Loading branch information
utahta committed Feb 6, 2017
1 parent 9239797 commit 3b9ad2b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 8 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ fmt:
test:
@go test -v -race

bench:
@go test -bench .
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![GitHub release](https://img.shields.io/github/release/utahta/go-cronowriter.svg)](https://github.com/utahta/go-cronowriter/releases)
[![Build Status](https://travis-ci.org/utahta/go-cronowriter.svg?branch=master)](https://travis-ci.org/utahta/go-cronowriter)

This is a simple file writer that writes message to a set of output files, the names of which are constructed like cronolog.
This is a simple file writer that writes message to a set of output files, the names of which are constructed time-based format like cronolog.

## Install

Expand Down Expand Up @@ -48,6 +48,14 @@ with Mutex
w := writer.MustNew("/path/to/example.log.%Y%m%d", writer.WithMutex())
```

with Debug (stdout and stderr)
```go
w := writer.MustNew("/path/to/example.log.%Y%m%d", writer.WithDebug())

// output file, stdout and stderr
// /path/to/2017/02/04/example.log
```

## Format

See [lestrrat/go-strftime#supported-conversion-specifications](https://github.com/lestrrat/go-strftime#supported-conversion-specifications)
Expand Down
40 changes: 33 additions & 7 deletions writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@ type cronoWriter struct {
fp *os.File
loc *time.Location
mux sync.Locker
stdout io.Writer
stderr io.Writer
}

type option func(*cronoWriter)

type noopWriter struct{}

func (*noopWriter) Write([]byte) (int, error) {
return 0, nil // no-op
}

var (
_ io.WriteCloser = &cronoWriter{} // check if object implements interface
now func() time.Time = time.Now // for test
waitCloseDuration = 5 * time.Second
_ io.WriteCloser = &cronoWriter{} // check if object implements interface
now func() time.Time = time.Now // for test
)

// New returns a cronoWriter with the given pattern and options.
Expand All @@ -39,6 +46,8 @@ func New(pattern string, options ...option) (*cronoWriter, error) {
fp: nil,
loc: time.Local,
mux: new(NoMutex), // default mutex off
stdout: &noopWriter{},
stderr: &noopWriter{},
}

for _, option := range options {
Expand Down Expand Up @@ -69,6 +78,13 @@ func WithMutex() option {
}
}

func WithDebug() option {
return func(c *cronoWriter) {
c.stdout = os.Stdout
c.stderr = os.Stderr
}
}

func (c *cronoWriter) Write(b []byte) (int, error) {
c.mux.Lock()
defer c.mux.Unlock()
Expand All @@ -81,23 +97,23 @@ func (c *cronoWriter) Write(b []byte) (int, error) {
if fp == nil {
return
}
time.Sleep(waitCloseDuration) // any ideas?
fp.Close()
}(c.fp)

dir := filepath.Dir(path)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return 0, err
return c.write(nil, err)
}

fp, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
return 0, err
return c.write(nil, err)
}
c.path = path
c.fp = fp
}
return c.fp.Write(b)

return c.write(b, nil)
}

func (c *cronoWriter) Close() error {
Expand All @@ -106,3 +122,13 @@ func (c *cronoWriter) Close() error {

return c.fp.Close()
}

func (c *cronoWriter) write(b []byte, err error) (int, error) {
if err != nil {
c.stderr.Write([]byte(err.Error()))
return 0, err
}

c.stdout.Write(b)
return c.fp.Write(b)
}
48 changes: 48 additions & 0 deletions writer_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package writer

import (
"io/ioutil"
"path/filepath"
"testing"
)

func BenchmarkCronoWriter_Write(b *testing.B) {
stubNow("2017-02-06 20:30:00 +0900")
tmpDir, err := ioutil.TempDir("", "cronowriter")
if err != nil {
b.Fatal(err)
}

c := MustNew(filepath.Join(tmpDir, "benchmark.log.%Y%m%d"))
for i := 0; i < b.N; i++ {
c.Write([]byte("abcdefg"))
}
}

func BenchmarkCronoWriter_WriteWithMutex(b *testing.B) {
stubNow("2017-02-06 20:30:00 +0900")
tmpDir, err := ioutil.TempDir("", "cronowriter")
if err != nil {
b.Fatal(err)
}

c := MustNew(filepath.Join(tmpDir, "benchmark.log.%Y%m%d"), WithMutex())
for i := 0; i < b.N; i++ {
c.Write([]byte("abcdefg"))
}
}

func BenchmarkCronoWriter_WriteWithDebug(b *testing.B) {
stubNow("2017-02-06 20:30:00 +0900")
tmpDir, err := ioutil.TempDir("", "cronowriter")
if err != nil {
b.Fatal(err)
}

c := MustNew(filepath.Join(tmpDir, "benchmark.log.%Y%m%d"), WithDebug())
c.stdout = ioutil.Discard
c.stderr = ioutil.Discard
for i := 0; i < b.N; i++ {
c.Write([]byte("abcdefg"))
}
}

0 comments on commit 3b9ad2b

Please sign in to comment.