Skip to content
Merged
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
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ log.D.Fmt("the level is %s", "debug")
log.T.Fmt("the level is %s", "trace")
```

### Exclude timestamp

When running under systemd it is nice to not include the redundant timestamp
directly from the logging package (since journald will already insert one). To
exclude the timestamp simply set the `ULOG_NOTIMESTAMP` environment variable
to `true`.

e.g. in a systemd unit file

```
[Service]
# ...
Environment="ULOG_NOTIMESTAMP=true"
```


### License

The `cattlecloud.net/go/ulog` module is open source under the [BSD-3-Clause](LICENSE) license.
50 changes: 34 additions & 16 deletions ulog.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package ulog

import (
"fmt"
"os"
"strconv"
"time"
)
Expand All @@ -21,6 +22,7 @@ const (
type Log struct {
name string
level int
short bool

E Output // error logs
W Output // warn logs
Expand All @@ -33,14 +35,18 @@ type Output interface {
Fmt(string, ...any)
}

type standard struct {
type format struct {
prefix string
name string
short bool
}

func (s *standard) Fmt(msg string, args ...any) {
now := time.Now().Format("01/02 15:04:05")
complete := now + " " + s.prefix + " [" + s.name + "] " + fmt.Sprintf(msg, args...)
func (s *format) Fmt(msg string, args ...any) {
complete := s.prefix + " [" + s.name + "] " + fmt.Sprintf(msg, args...)
if !s.short {
now := time.Now().Format("01/02 15:04:05")
complete = now + " " + complete
}
fmt.Println(complete)
}

Expand All @@ -50,7 +56,11 @@ func (null) Fmt(string, ...any) {
// do nothing
}

func output(name string, minimum, level int) Output {
func output(name string, short bool, minimum, level int) Output {
if level > minimum {
return null{}
}

var prefix string
switch level {
case Error:
Expand All @@ -65,31 +75,35 @@ func output(name string, minimum, level int) Output {
prefix = "TRACE"
}

if level <= minimum {
return &standard{
prefix: prefix,
name: name,
}
return &format{
prefix: prefix,
name: name,
short: shorten(short),
}
}

return null{}
func shorten(force bool) bool {
env := os.Getenv("ULOG_NOTIMESTAMP")
v, _ := strconv.ParseBool(env)
return v || force
}

func New(name string, opts ...Option) *Log {
log := &Log{
name: name,
level: Debug,
short: false,
}

for _, opt := range opts {
opt(log)
}

log.E = output(name, log.level, Error)
log.W = output(name, log.level, Warn)
log.I = output(name, log.level, Info)
log.D = output(name, log.level, Debug)
log.T = output(name, log.level, Trace)
log.E = output(name, log.short, log.level, Error)
log.W = output(name, log.short, log.level, Warn)
log.I = output(name, log.short, log.level, Info)
log.D = output(name, log.short, log.level, Debug)
log.T = output(name, log.short, log.level, Trace)

return log
}
Expand All @@ -109,3 +123,7 @@ func SetLevel(value int) Option {
}
return func(l *Log) { l.level = value }
}

func SetNoTimestamp() Option {
return func(l *Log) { l.short = true }
}
9 changes: 9 additions & 0 deletions ulog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,12 @@ func Test_SetLevel(t *testing.T) {

t.Log("complete")
}

func Test_SetNoTimestamp(t *testing.T) {
t.Parallel()

t.Run("shorten", func(_ *testing.T) {
log := New("test-timestamp", SetNoTimestamp())
log.I.Fmt("no timestamp here")
})
}
Loading