diff --git a/.github/workflows/jsonschema.yml b/.github/workflows/jsonschema.yml new file mode 100644 index 00000000..4fc63672 --- /dev/null +++ b/.github/workflows/jsonschema.yml @@ -0,0 +1,20 @@ +name: JSON Schema Check + +on: + push: + pull_request: + +jobs: + json-schema-check: + runs-on: ubuntu-22.04 + container: python:3.10-alpine3.16 + steps: + - uses: actions/checkout@v3 + - name: Test + run: | + pip install jsonschema==4.14.0 + for f in $(find config/ -name '*.json') + do + echo "Checking $f" + jsonschema -i $f config-schema.json + done diff --git a/.gitignore b/.gitignore index 20bf50a1..9cdef23e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,9 @@ .DS_Store ftpserver +ftpserver.json +ftpserver.log ci-info .idea/ -.vscode/ *.pem -ftpserver.json gdrive_token_gdrive.json -__debug__bin +__* diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..434c719a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch (log_file)", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}", + "args": ["-conf", "${workspaceFolder}/config/samples/log_file.json"] + } + ] +} \ No newline at end of file diff --git a/config-schema.json b/config-schema.json index ddcea49d..e2510234 100644 --- a/config-schema.json +++ b/config-schema.json @@ -86,10 +86,6 @@ "type": "object", "default": {}, "title": "The logging options", - "required": [ - "ftp_exchanges", - "file_accesses" - ], "properties": { "ftp_exchanges": { "type": "boolean", @@ -106,11 +102,20 @@ "examples": [ true ] + }, + "file": { + "type": "string", + "default": "ftpserver.log", + "title": "Perform logging to a file", + "examples": [ + "ftpserver.log" + ] } }, "examples": [{ "ftp_exchanges": true, - "file_accesses": true + "file_accesses": true, + "file": "ftpserver.log" }] }, "tls": { diff --git a/config/confpar/confpar.go b/config/confpar/confpar.go index 19f6ee92..36c1b619 100644 --- a/config/confpar/confpar.go +++ b/config/confpar/confpar.go @@ -28,8 +28,9 @@ type PortRange struct { // Logging defines how we will log accesses type Logging struct { - FtpExchanges bool `json:"ftp_exchanges"` // Log all ftp exchanges - FileAccesses bool `json:"file_accesses"` // Log all file accesses + FtpExchanges bool `json:"ftp_exchanges"` // Log all ftp exchanges + FileAccesses bool `json:"file_accesses"` // Log all file accesses + File string `json:"file"` // Log file } // TLS define the TLS Config diff --git a/config/confpar/samples/behind_nat.json b/config/samples/behind_nat.json similarity index 100% rename from config/confpar/samples/behind_nat.json rename to config/samples/behind_nat.json diff --git a/config/samples/log_file.json b/config/samples/log_file.json new file mode 100644 index 00000000..90e94a51 --- /dev/null +++ b/config/samples/log_file.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://raw.githubusercontent.com/fclairamb/ftpserver/main/config-schema.json", + "logging": { + "file": "ftpserver.log" + }, + "accesses": [] +} diff --git a/go.mod b/go.mod index 32b9d5bc..c734c191 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( require ( cloud.google.com/go/compute v1.7.0 // indirect github.com/dropbox/dropbox-sdk-go-unofficial v5.6.0+incompatible // indirect - github.com/go-kit/log v0.2.1 // indirect + github.com/go-kit/log v0.2.1 github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.5.2 // indirect diff --git a/main.go b/main.go index c6e9d4a6..7e56a762 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "flag" + "io" "io/ioutil" "os" "os/signal" @@ -10,7 +11,8 @@ import ( "time" ftpserver "github.com/fclairamb/ftpserverlib" - "github.com/fclairamb/go-log/gokit" + gkwrap "github.com/fclairamb/go-log/gokit" + gokit "github.com/go-kit/log" "github.com/fclairamb/ftpserver/config" "github.com/fclairamb/ftpserver/server" @@ -32,10 +34,7 @@ func main() { flag.Parse() // Setting up the logger - logger := gokit.New().With( - "ts", gokit.GKDefaultTimestampUTC, - "caller", gokit.GKDefaultCaller, - ) + logger := gkwrap.New() logger.Info("FTP server", "version", BuildVersion, "date", BuildDate, "commit", Commit) @@ -52,7 +51,7 @@ func main() { if _, err := os.Stat(confFile); err != nil && os.IsNotExist(err) { logger.Warn("No conf file, creating one", "confFile", confFile) - if err := ioutil.WriteFile(confFile, confFileContent(), 0600); err != nil { // nolint: gomnd + if err := ioutil.WriteFile(confFile, confFileContent(), 0600); err != nil { //nolint: gomnd logger.Warn("Couldn't create conf file", "confFile", confFile) } } @@ -65,6 +64,22 @@ func main() { return } + // Now is a good time to open a logging file + if conf.Content.Logging.File != "" { + writer, err := os.OpenFile(conf.Content.Logging.File, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) //nolint:gomnd + + if err != nil { + logger.Error("Can't open log file", "err", err) + + return + } + + logger = gkwrap.NewWrap(gokit.NewLogfmtLogger(io.MultiWriter(writer, os.Stdout))).With( + "ts", gokit.DefaultTimestampUTC, + "caller", gokit.DefaultCaller, + ) + } + // Loading the driver var errNewServer error driver, errNewServer = server.NewServer(conf, logger.With("component", "driver"))