Skip to content

Commit

Permalink
feat(logging): date time layout (#6333)
Browse files Browse the repository at this point in the history
This adds a date time layout option for the log file path.

Closes #6136
  • Loading branch information
james-d-elliott committed Nov 26, 2023
1 parent 7be83ca commit 786985e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
15 changes: 12 additions & 3 deletions docs/content/en/configuration/miscellaneous/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@ Logs can be stored in a file when file path is provided. Otherwise logs are writ
level to `debug` or `trace` this will generate large amount of log entries. Administrators will need to ensure that
they rotate and/or truncate the logs over time to prevent significant long-term disk usage.

If you include the value `%d` in the filename it will replace this value with a date time indicative of the time
the logger was initialized using [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339) as the format which is
represented as `2006-01-02T15:04:05Z07:00` in go.
There are two replacements that exist in this string for the purpose of including the dete. The `%d` value which just
uses the [RFC3339] layout, and the `{datetime}` replacement which by
default uses the [RFC3339] layout, but optionally can be suffixed with the
[Go Layout](https://pkg.go.dev/time#pkg-constants) semantics in the format of `{datetime:<layout>}` where `<layout>` is
the layout supported by Go.

#### File Path Examples

Expand All @@ -98,6 +100,13 @@ log:
file_path: /config/authelia.%d.log
```

__Date Time Example (with custom layout):__

```yaml
log:
file_path: /config/authelia.{datetime:Mon Jan 2 15:04:05 MST 2006}.log
```

### keep_stdout

{{< confkey type="boolean" default="false" required="no" >}}
Expand Down
21 changes: 20 additions & 1 deletion internal/logging/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package logging
import (
"io"
"os"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -44,6 +45,24 @@ func InitializeLogger(config schema.Log, log bool) (err error) {
return ConfigureLogger(config, log)
}

var reFormatFilePath = regexp.MustCompile(`(%d|\{datetime(:([^}]+))?})`)

func FormatFilePath(in string, now time.Time) (out string) {
matches := reFormatFilePath.FindStringSubmatch(in)

if len(matches) == 0 {
return in
}

layout := time.RFC3339

if len(matches[3]) != 0 {
layout = matches[3]
}

return strings.Replace(in, matches[0], now.Format(layout), 1)
}

// ConfigureLogger configures the default loggers level, formatting, and the output destinations.
func ConfigureLogger(config schema.Log, log bool) (err error) {
setLevelStr(config.Level, log)
Expand All @@ -61,7 +80,7 @@ func ConfigureLogger(config schema.Log, log bool) (err error) {
case config.FilePath != "":
var file *os.File

if file, err = os.OpenFile(strings.ReplaceAll(config.FilePath, "%d", time.Now().Format(time.RFC3339)), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600); err != nil {
if file, err = os.OpenFile(FormatFilePath(config.FilePath, time.Now()), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600); err != nil {
return err
}

Expand Down
41 changes: 41 additions & 0 deletions internal/logging/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"runtime"
"testing"
"time"

"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
Expand All @@ -14,6 +15,46 @@ import (
"github.com/authelia/authelia/v4/internal/configuration/schema"
)

func TestFormatFilePath(t *testing.T) {
testCases := []struct {
name string
have string
now time.Time
expected string
}{
{
"ShouldReturnInput",
"abc 123",
time.Unix(0, 0).UTC(),
"abc 123",
},
{
"ShouldReturnStandardWithDateTime",
"abc %d 123",
time.Unix(0, 0).UTC(),
"abc 1970-01-01T00:00:00Z 123",
},
{
"ShouldReturnStandardWithDateTimeFormatter",
"abc {datetime} 123",
time.Unix(0, 0).UTC(),
"abc 1970-01-01T00:00:00Z 123",
},
{
"ShouldReturnStandardWithDateTimeCustomLayout",
"abc {datetime:Mon Jan 2 15:04:05 MST 2006} 123",
time.Unix(0, 0).UTC(),
"abc Thu Jan 1 00:00:00 UTC 1970 123",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.expected, FormatFilePath(tc.have, tc.now))
})
}
}

func TestShouldWriteLogsToFile(t *testing.T) {
dir := t.TempDir()

Expand Down

0 comments on commit 786985e

Please sign in to comment.