feat: Add basic structured logger
This commit is contained in:
@@ -34,7 +34,7 @@ var inventoryFindCmd = &cobra.Command{
|
|||||||
|
|
||||||
viper.GetString(expressionFlag),
|
viper.GetString(expressionFlag),
|
||||||
|
|
||||||
logging.NewLogger().PrintHeader,
|
logging.NewCSVLogger().PrintHeader,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ var inventoryListCmd = &cobra.Command{
|
|||||||
viper.GetString(nameFlag),
|
viper.GetString(nameFlag),
|
||||||
viper.GetInt(limitFlag),
|
viper.GetInt(limitFlag),
|
||||||
|
|
||||||
logging.NewLogger().PrintHeader,
|
logging.NewCSVLogger().PrintHeader,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ var inventoryStatCmd = &cobra.Command{
|
|||||||
|
|
||||||
viper.GetString(nameFlag),
|
viper.GetString(nameFlag),
|
||||||
|
|
||||||
logging.NewLogger().PrintHeader,
|
logging.NewCSVLogger().PrintHeader,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ var operationArchiveCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(passwordFlag),
|
Password: viper.GetString(passwordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logging.NewLogger().PrintHeaderEvent,
|
logging.NewCSVLogger().PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
files := make(chan config.FileConfig)
|
files := make(chan config.FileConfig)
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ var operationDeleteCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(passwordFlag),
|
Password: viper.GetString(passwordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logging.NewLogger().PrintHeaderEvent,
|
logging.NewCSVLogger().PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
return ops.Delete(viper.GetString(nameFlag))
|
return ops.Delete(viper.GetString(nameFlag))
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ var operationMoveCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(passwordFlag),
|
Password: viper.GetString(passwordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logging.NewLogger().PrintHeaderEvent,
|
logging.NewCSVLogger().PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
return ops.Move(viper.GetString(fromFlag), viper.GetString(toFlag))
|
return ops.Move(viper.GetString(fromFlag), viper.GetString(toFlag))
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ var operationRestoreCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(passwordFlag),
|
Password: viper.GetString(passwordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logging.NewLogger().PrintHeaderEvent,
|
logging.NewCSVLogger().PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
return ops.Restore(
|
return ops.Restore(
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ var operationUpdateCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(passwordFlag),
|
Password: viper.GetString(passwordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logging.NewLogger().PrintHeaderEvent,
|
logging.NewCSVLogger().PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
files := make(chan config.FileConfig)
|
files := make(chan config.FileConfig)
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ var recoveryFetchCmd = &cobra.Command{
|
|||||||
viper.GetString(toFlag),
|
viper.GetString(toFlag),
|
||||||
viper.GetBool(previewFlag),
|
viper.GetBool(previewFlag),
|
||||||
|
|
||||||
logging.NewLogger().PrintHeader,
|
logging.NewCSVLogger().PrintHeader,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ var recoveryIndexCmd = &cobra.Command{
|
|||||||
return signature.VerifyHeader(hdr, isRegular, viper.GetString(signatureFlag), recipient)
|
return signature.VerifyHeader(hdr, isRegular, viper.GetString(signatureFlag), recipient)
|
||||||
},
|
},
|
||||||
|
|
||||||
logging.NewLogger().PrintHeader,
|
logging.NewCSVLogger().PrintHeader,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ var recoveryQueryCmd = &cobra.Command{
|
|||||||
viper.GetInt(recordFlag),
|
viper.GetInt(recordFlag),
|
||||||
viper.GetInt(blockFlag),
|
viper.GetInt(blockFlag),
|
||||||
|
|
||||||
logging.NewLogger().PrintHeader,
|
logging.NewCSVLogger().PrintHeader,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
@@ -126,7 +125,8 @@ var serveFTPCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := logging.NewLogger()
|
csvLogger := logging.NewCSVLogger()
|
||||||
|
structuredLogger := logging.NewJSONLogger()
|
||||||
|
|
||||||
readOps := operations.NewOperations(
|
readOps := operations.NewOperations(
|
||||||
config.BackendConfig{
|
config.BackendConfig{
|
||||||
@@ -155,7 +155,7 @@ var serveFTPCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(encryptionPasswordFlag),
|
Password: viper.GetString(encryptionPasswordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logger.PrintHeaderEvent,
|
csvLogger.PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
writeOps := operations.NewOperations(
|
writeOps := operations.NewOperations(
|
||||||
@@ -185,7 +185,7 @@ var serveFTPCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(signaturePasswordFlag),
|
Password: viper.GetString(signaturePasswordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logger.PrintHeaderEvent,
|
csvLogger.PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
stfs := sfs.NewFileSystem(
|
stfs := sfs.NewFileSystem(
|
||||||
@@ -205,7 +205,8 @@ var serveFTPCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
true, // FTP needs read permission for `STOR` command even if O_WRONLY is set
|
true, // FTP needs read permission for `STOR` command even if O_WRONLY is set
|
||||||
|
|
||||||
logger.PrintHeader,
|
csvLogger.PrintHeader,
|
||||||
|
structuredLogger,
|
||||||
)
|
)
|
||||||
|
|
||||||
fs, err := cache.NewCacheFilesystem(
|
fs, err := cache.NewCacheFilesystem(
|
||||||
@@ -229,10 +230,12 @@ var serveFTPCmd = &cobra.Command{
|
|||||||
)
|
)
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
if viper.GetBool(verboseFlag) {
|
||||||
srv.Logger = &ftp.Logger{}
|
srv.Logger = &logging.JSONLogger{}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Listening on", viper.GetString(laddrFlag))
|
structuredLogger.Info("HTTP server listening", map[string]interface{}{
|
||||||
|
"laddr": viper.GetString(laddrFlag),
|
||||||
|
})
|
||||||
|
|
||||||
return srv.ListenAndServe()
|
return srv.ListenAndServe()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
@@ -85,7 +84,8 @@ var serveHTTPCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := logging.NewLogger()
|
csvLogger := logging.NewCSVLogger()
|
||||||
|
structuredLogger := logging.NewJSONLogger()
|
||||||
|
|
||||||
readOps := operations.NewOperations(
|
readOps := operations.NewOperations(
|
||||||
config.BackendConfig{
|
config.BackendConfig{
|
||||||
@@ -114,7 +114,7 @@ var serveHTTPCmd = &cobra.Command{
|
|||||||
Password: viper.GetString(passwordFlag),
|
Password: viper.GetString(passwordFlag),
|
||||||
},
|
},
|
||||||
|
|
||||||
logger.PrintHeaderEvent,
|
csvLogger.PrintHeaderEvent,
|
||||||
)
|
)
|
||||||
|
|
||||||
stfs := sfs.NewFileSystem(
|
stfs := sfs.NewFileSystem(
|
||||||
@@ -129,7 +129,8 @@ var serveHTTPCmd = &cobra.Command{
|
|||||||
nil, // We never write
|
nil, // We never write
|
||||||
false, // We never write
|
false, // We never write
|
||||||
|
|
||||||
logger.PrintHeader,
|
csvLogger.PrintHeader,
|
||||||
|
structuredLogger,
|
||||||
)
|
)
|
||||||
|
|
||||||
fs, err := cache.NewCacheFilesystem(
|
fs, err := cache.NewCacheFilesystem(
|
||||||
@@ -143,7 +144,9 @@ var serveHTTPCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Listening on", viper.GetString(laddrFlag))
|
structuredLogger.Info("FTP server listening", map[string]interface{}{
|
||||||
|
"laddr": viper.GetString(laddrFlag),
|
||||||
|
})
|
||||||
|
|
||||||
return http.ListenAndServe(
|
return http.ListenAndServe(
|
||||||
viper.GetString(laddrFlag),
|
viper.GetString(laddrFlag),
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata"
|
models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata"
|
||||||
"github.com/pojntfx/stfs/internal/ioext"
|
"github.com/pojntfx/stfs/internal/ioext"
|
||||||
|
"github.com/pojntfx/stfs/internal/logging"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
"github.com/pojntfx/stfs/pkg/inventory"
|
"github.com/pojntfx/stfs/pkg/inventory"
|
||||||
"github.com/pojntfx/stfs/pkg/operations"
|
"github.com/pojntfx/stfs/pkg/operations"
|
||||||
@@ -68,6 +69,7 @@ type File struct {
|
|||||||
cleanWriteBuf func() error
|
cleanWriteBuf func() error
|
||||||
|
|
||||||
onHeader func(hdr *models.Header)
|
onHeader func(hdr *models.Header)
|
||||||
|
log *logging.JSONLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFile(
|
func NewFile(
|
||||||
@@ -87,6 +89,7 @@ func NewFile(
|
|||||||
info os.FileInfo,
|
info os.FileInfo,
|
||||||
|
|
||||||
onHeader func(hdr *models.Header),
|
onHeader func(hdr *models.Header),
|
||||||
|
log *logging.JSONLogger,
|
||||||
) *File {
|
) *File {
|
||||||
return &File{
|
return &File{
|
||||||
readOps: readOps,
|
readOps: readOps,
|
||||||
@@ -105,11 +108,14 @@ func NewFile(
|
|||||||
info: info,
|
info: info,
|
||||||
|
|
||||||
onHeader: onHeader,
|
onHeader: onHeader,
|
||||||
|
log: log,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) syncWithoutLocking() error {
|
func (f *File) syncWithoutLocking() error {
|
||||||
log.Println("File.syncWithoutLocking", f.name)
|
f.log.Trace("File.syncWithoutLocking", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return ErrIsDirectory
|
return ErrIsDirectory
|
||||||
@@ -163,7 +169,9 @@ func (f *File) syncWithoutLocking() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) closeWithoutLocking() error {
|
func (f *File) closeWithoutLocking() error {
|
||||||
log.Println("File.closeWithoutLocking", f.name)
|
f.log.Trace("File.closeWithoutLocking", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
if f.readOpReader != nil {
|
if f.readOpReader != nil {
|
||||||
if err := f.readOpReader.Close(); err != nil {
|
if err := f.readOpReader.Close(); err != nil {
|
||||||
@@ -196,6 +204,10 @@ func (f *File) closeWithoutLocking() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) enterWriteMode() error {
|
func (f *File) enterWriteMode() error {
|
||||||
|
f.log.Trace("File.enterWriteMode", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
if f.readOpReader != nil || f.readOpWriter != nil {
|
if f.readOpReader != nil || f.readOpWriter != nil {
|
||||||
if err := f.closeWithoutLocking(); err != nil {
|
if err := f.closeWithoutLocking(); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -265,7 +277,11 @@ func (f *File) enterWriteMode() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) seekWithoutLocking(offset int64, whence int) (int64, error) {
|
func (f *File) seekWithoutLocking(offset int64, whence int) (int64, error) {
|
||||||
log.Println("File.seekWithoutLocking", f.name, offset, whence)
|
f.log.Trace("File.seekWithoutLocking", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"offset": offset,
|
||||||
|
"whence": whence,
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return -1, ErrIsDirectory
|
return -1, ErrIsDirectory
|
||||||
@@ -341,19 +357,26 @@ func (f *File) seekWithoutLocking(offset int64, whence int) (int64, error) {
|
|||||||
|
|
||||||
// Inventory
|
// Inventory
|
||||||
func (f *File) Name() string {
|
func (f *File) Name() string {
|
||||||
log.Println("File.Name", f.name)
|
f.log.Trace("File.Name", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.name
|
return f.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) Stat() (os.FileInfo, error) {
|
func (f *File) Stat() (os.FileInfo, error) {
|
||||||
log.Println("File.Stat", f.name)
|
f.log.Trace("File.Stat", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.info, nil
|
return f.info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
||||||
log.Println("File.Readdir", f.name, count)
|
f.log.Trace("File.Readdir", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"count": count,
|
||||||
|
})
|
||||||
|
|
||||||
hdrs, err := inventory.List(
|
hdrs, err := inventory.List(
|
||||||
f.metadata,
|
f.metadata,
|
||||||
@@ -369,14 +392,17 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
|||||||
|
|
||||||
fileInfos := []os.FileInfo{}
|
fileInfos := []os.FileInfo{}
|
||||||
for _, hdr := range hdrs {
|
for _, hdr := range hdrs {
|
||||||
fileInfos = append(fileInfos, NewFileInfo(hdr))
|
fileInfos = append(fileInfos, NewFileInfo(hdr, f.log))
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileInfos, nil
|
return fileInfos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) Readdirnames(n int) ([]string, error) {
|
func (f *File) Readdirnames(n int) ([]string, error) {
|
||||||
log.Println("File.Readdirnames", f.name, n)
|
f.log.Trace("File.Readdirnames", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"n": n,
|
||||||
|
})
|
||||||
|
|
||||||
dirs, err := f.Readdir(n)
|
dirs, err := f.Readdir(n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -393,7 +419,10 @@ func (f *File) Readdirnames(n int) ([]string, error) {
|
|||||||
|
|
||||||
// Read operations
|
// Read operations
|
||||||
func (f *File) Read(p []byte) (n int, err error) {
|
func (f *File) Read(p []byte) (n int, err error) {
|
||||||
log.Println("File.Read", f.name, len(p))
|
f.log.Trace("File.Read", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"p": len(p),
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return -1, ErrIsDirectory
|
return -1, ErrIsDirectory
|
||||||
@@ -458,7 +487,11 @@ func (f *File) Read(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) ReadAt(p []byte, off int64) (n int, err error) {
|
func (f *File) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
log.Println("File.ReadAt", f.name, p, off)
|
f.log.Trace("File.ReadAt", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"p": len(p),
|
||||||
|
"off": off,
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return -1, ErrIsDirectory
|
return -1, ErrIsDirectory
|
||||||
@@ -477,7 +510,11 @@ func (f *File) ReadAt(p []byte, off int64) (n int, err error) {
|
|||||||
|
|
||||||
// Read/write operations
|
// Read/write operations
|
||||||
func (f *File) Seek(offset int64, whence int) (int64, error) {
|
func (f *File) Seek(offset int64, whence int) (int64, error) {
|
||||||
log.Println("File.Seek", f.name, offset, whence)
|
f.log.Trace("File.Seek", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"offset": offset,
|
||||||
|
"whence": whence,
|
||||||
|
})
|
||||||
|
|
||||||
f.ioLock.Lock()
|
f.ioLock.Lock()
|
||||||
defer f.ioLock.Unlock()
|
defer f.ioLock.Unlock()
|
||||||
@@ -487,7 +524,10 @@ func (f *File) Seek(offset int64, whence int) (int64, error) {
|
|||||||
|
|
||||||
// Write operations
|
// Write operations
|
||||||
func (f *File) Write(p []byte) (n int, err error) {
|
func (f *File) Write(p []byte) (n int, err error) {
|
||||||
log.Println("File.Write", f.name, len(p))
|
f.log.Trace("File.Write", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"p": len(p),
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return -1, ErrIsDirectory
|
return -1, ErrIsDirectory
|
||||||
@@ -515,7 +555,11 @@ func (f *File) Write(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) WriteAt(p []byte, off int64) (n int, err error) {
|
func (f *File) WriteAt(p []byte, off int64) (n int, err error) {
|
||||||
log.Println("File.WriteAt", f.name, p, off)
|
f.log.Trace("File.WriteAt", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"p": len(p),
|
||||||
|
"off": off,
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return -1, ErrIsDirectory
|
return -1, ErrIsDirectory
|
||||||
@@ -540,7 +584,10 @@ func (f *File) WriteAt(p []byte, off int64) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) WriteString(s string) (ret int, err error) {
|
func (f *File) WriteString(s string) (ret int, err error) {
|
||||||
log.Println("File.WriteString", f.name, s)
|
f.log.Trace("File.WriteString", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"s": len(s),
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return -1, ErrIsDirectory
|
return -1, ErrIsDirectory
|
||||||
@@ -561,7 +608,10 @@ func (f *File) WriteString(s string) (ret int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) Truncate(size int64) error {
|
func (f *File) Truncate(size int64) error {
|
||||||
log.Println("File.Truncate", f.name, size)
|
f.log.Trace("File.Truncate", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
"size": size,
|
||||||
|
})
|
||||||
|
|
||||||
if f.info.IsDir() {
|
if f.info.IsDir() {
|
||||||
return ErrIsDirectory
|
return ErrIsDirectory
|
||||||
@@ -583,7 +633,9 @@ func (f *File) Truncate(size int64) error {
|
|||||||
|
|
||||||
// Cleanup operations
|
// Cleanup operations
|
||||||
func (f *File) Sync() error {
|
func (f *File) Sync() error {
|
||||||
log.Println("File.Sync", f.name)
|
f.log.Trace("File.Sync", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
f.ioLock.Lock()
|
f.ioLock.Lock()
|
||||||
defer f.ioLock.Unlock()
|
defer f.ioLock.Unlock()
|
||||||
@@ -592,7 +644,9 @@ func (f *File) Sync() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) Close() error {
|
func (f *File) Close() error {
|
||||||
log.Println("File.Close", f.name)
|
f.log.Debug("File.Close", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
f.ioLock.Lock()
|
f.ioLock.Lock()
|
||||||
defer f.ioLock.Unlock()
|
defer f.ioLock.Unlock()
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ package fs
|
|||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pojntfx/stfs/internal/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
@@ -16,50 +17,70 @@ type FileInfo struct {
|
|||||||
mode fs.FileMode
|
mode fs.FileMode
|
||||||
modTime time.Time
|
modTime time.Time
|
||||||
isDir bool
|
isDir bool
|
||||||
|
|
||||||
|
log *logging.JSONLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileInfo(hdr *tar.Header) *FileInfo {
|
func NewFileInfo(
|
||||||
|
hdr *tar.Header,
|
||||||
|
|
||||||
|
log *logging.JSONLogger,
|
||||||
|
) *FileInfo {
|
||||||
return &FileInfo{
|
return &FileInfo{
|
||||||
name: hdr.FileInfo().Name(),
|
name: hdr.FileInfo().Name(),
|
||||||
size: hdr.FileInfo().Size(),
|
size: hdr.FileInfo().Size(),
|
||||||
mode: hdr.FileInfo().Mode(),
|
mode: hdr.FileInfo().Mode(),
|
||||||
modTime: hdr.FileInfo().ModTime(),
|
modTime: hdr.FileInfo().ModTime(),
|
||||||
isDir: hdr.FileInfo().IsDir(),
|
isDir: hdr.FileInfo().IsDir(),
|
||||||
|
|
||||||
|
log: log,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileInfo) Name() string {
|
func (f *FileInfo) Name() string {
|
||||||
log.Println("FileInfo.Name", f.name)
|
f.log.Trace("FileInfo.Name", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.name
|
return f.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileInfo) Size() int64 {
|
func (f *FileInfo) Size() int64 {
|
||||||
log.Println("FileInfo.Size", f.name)
|
f.log.Trace("FileInfo.Size", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.size
|
return f.size
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileInfo) Mode() os.FileMode {
|
func (f *FileInfo) Mode() os.FileMode {
|
||||||
log.Println("FileInfo.Mode", f.name)
|
f.log.Trace("FileInfo.Mode", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.mode
|
return f.mode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileInfo) ModTime() time.Time {
|
func (f *FileInfo) ModTime() time.Time {
|
||||||
log.Println("FileInfo.ModTime", f.name)
|
f.log.Trace("FileInfo.ModTime", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.modTime
|
return f.modTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileInfo) IsDir() bool {
|
func (f *FileInfo) IsDir() bool {
|
||||||
log.Println("FileInfo.IsDir", f.name)
|
f.log.Trace("FileInfo.IsDir", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.isDir
|
return f.isDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileInfo) Sys() interface{} {
|
func (f *FileInfo) Sys() interface{} {
|
||||||
log.Println("FileInfo.Sys", f.name)
|
f.log.Trace("FileInfo.Sys", map[string]interface{}{
|
||||||
|
"name": f.name,
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
@@ -14,6 +13,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata"
|
models "github.com/pojntfx/stfs/internal/db/sqlite/models/metadata"
|
||||||
|
"github.com/pojntfx/stfs/internal/logging"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
"github.com/pojntfx/stfs/pkg/inventory"
|
"github.com/pojntfx/stfs/pkg/inventory"
|
||||||
"github.com/pojntfx/stfs/pkg/operations"
|
"github.com/pojntfx/stfs/pkg/operations"
|
||||||
@@ -24,6 +24,10 @@ var (
|
|||||||
ErrNotImplemented = errors.New("not implemented")
|
ErrNotImplemented = errors.New("not implemented")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FileSystemNameSTFS = "STFS"
|
||||||
|
)
|
||||||
|
|
||||||
type FileSystem struct {
|
type FileSystem struct {
|
||||||
readOps *operations.Operations
|
readOps *operations.Operations
|
||||||
writeOps *operations.Operations
|
writeOps *operations.Operations
|
||||||
@@ -35,6 +39,7 @@ type FileSystem struct {
|
|||||||
ignoreReadWritePermissions bool
|
ignoreReadWritePermissions bool
|
||||||
|
|
||||||
onHeader func(hdr *models.Header)
|
onHeader func(hdr *models.Header)
|
||||||
|
log *logging.JSONLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileSystem(
|
func NewFileSystem(
|
||||||
@@ -48,6 +53,7 @@ func NewFileSystem(
|
|||||||
ignorePermissionFlags bool,
|
ignorePermissionFlags bool,
|
||||||
|
|
||||||
onHeader func(hdr *models.Header),
|
onHeader func(hdr *models.Header),
|
||||||
|
log *logging.JSONLogger,
|
||||||
) afero.Fs {
|
) afero.Fs {
|
||||||
return &FileSystem{
|
return &FileSystem{
|
||||||
readOps: readOps,
|
readOps: readOps,
|
||||||
@@ -60,23 +66,31 @@ func NewFileSystem(
|
|||||||
ignoreReadWritePermissions: ignorePermissionFlags,
|
ignoreReadWritePermissions: ignorePermissionFlags,
|
||||||
|
|
||||||
onHeader: onHeader,
|
onHeader: onHeader,
|
||||||
|
log: log,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Name() string {
|
func (f *FileSystem) Name() string {
|
||||||
log.Println("FileSystem.Name")
|
f.log.Debug("FileSystem.Name", map[string]interface{}{
|
||||||
|
"name": FileSystemNameSTFS,
|
||||||
|
})
|
||||||
|
|
||||||
return "STFS"
|
return FileSystemNameSTFS
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Create(name string) (afero.File, error) {
|
func (f *FileSystem) Create(name string) (afero.File, error) {
|
||||||
log.Println("FileSystem.Name", name)
|
f.log.Debug("FileSystem.Name", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
})
|
||||||
|
|
||||||
return os.OpenFile(name, os.O_CREATE, 0666)
|
return os.OpenFile(name, os.O_CREATE, 0666)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) mknode(dir bool, name string, perm os.FileMode) error {
|
func (f *FileSystem) mknode(dir bool, name string, perm os.FileMode) error {
|
||||||
log.Println("FileSystem.mknode", name, perm)
|
f.log.Trace("FileSystem.mknode", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
"perm": perm,
|
||||||
|
})
|
||||||
|
|
||||||
usr, err := user.Current()
|
usr, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -150,13 +164,19 @@ func (f *FileSystem) mknode(dir bool, name string, perm os.FileMode) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Mkdir(name string, perm os.FileMode) error {
|
func (f *FileSystem) Mkdir(name string, perm os.FileMode) error {
|
||||||
log.Println("FileSystem.Mkdir", name, perm)
|
f.log.Debug("FileSystem.Mkdir", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
"perm": perm,
|
||||||
|
})
|
||||||
|
|
||||||
return f.mknode(true, name, perm)
|
return f.mknode(true, name, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) MkdirAll(path string, perm os.FileMode) error {
|
func (f *FileSystem) MkdirAll(path string, perm os.FileMode) error {
|
||||||
log.Println("FileSystem.MkdirAll", path, perm)
|
f.log.Debug("FileSystem.MkdirAll", map[string]interface{}{
|
||||||
|
"path": path,
|
||||||
|
"perm": perm,
|
||||||
|
})
|
||||||
|
|
||||||
parts := filepath.SplitList(path)
|
parts := filepath.SplitList(path)
|
||||||
currentPath := ""
|
currentPath := ""
|
||||||
@@ -177,13 +197,19 @@ func (f *FileSystem) MkdirAll(path string, perm os.FileMode) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Open(name string) (afero.File, error) {
|
func (f *FileSystem) Open(name string) (afero.File, error) {
|
||||||
log.Println("FileSystem.Open", name)
|
f.log.Debug("FileSystem.Open", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.OpenFile(name, os.O_RDWR, os.ModePerm)
|
return f.OpenFile(name, os.O_RDWR, os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
|
func (f *FileSystem) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
|
||||||
log.Println("FileSystem.OpenFile", name, flag, perm)
|
f.log.Debug("FileSystem.OpenFile", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
"flag": flag,
|
||||||
|
"perm": perm,
|
||||||
|
})
|
||||||
|
|
||||||
flags := &FileFlags{}
|
flags := &FileFlags{}
|
||||||
if flag&os.O_RDONLY != 0 {
|
if flag&os.O_RDONLY != 0 {
|
||||||
@@ -259,32 +285,42 @@ func (f *FileSystem) OpenFile(name string, flag int, perm os.FileMode) (afero.Fi
|
|||||||
f.getFileBuffer,
|
f.getFileBuffer,
|
||||||
|
|
||||||
path.Base(hdr.Name),
|
path.Base(hdr.Name),
|
||||||
NewFileInfo(hdr),
|
NewFileInfo(hdr, f.log),
|
||||||
|
|
||||||
f.onHeader,
|
f.onHeader,
|
||||||
|
f.log,
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Remove(name string) error {
|
func (f *FileSystem) Remove(name string) error {
|
||||||
log.Println("FileSystem.Remove", name)
|
f.log.Debug("FileSystem.Remove", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
})
|
||||||
|
|
||||||
return f.writeOps.Delete(name)
|
return f.writeOps.Delete(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) RemoveAll(path string) error {
|
func (f *FileSystem) RemoveAll(path string) error {
|
||||||
log.Println("FileSystem.RemoveAll", path)
|
f.log.Debug("FileSystem.RemoveAll", map[string]interface{}{
|
||||||
|
"path": path,
|
||||||
|
})
|
||||||
|
|
||||||
return f.writeOps.Delete(path)
|
return f.writeOps.Delete(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Rename(oldname, newname string) error {
|
func (f *FileSystem) Rename(oldname, newname string) error {
|
||||||
log.Println("FileSystem.Rename", oldname, newname)
|
f.log.Debug("FileSystem.Rename", map[string]interface{}{
|
||||||
|
"oldname": oldname,
|
||||||
|
"newname": newname,
|
||||||
|
})
|
||||||
|
|
||||||
return f.writeOps.Move(oldname, newname)
|
return f.writeOps.Move(oldname, newname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Stat(name string) (os.FileInfo, error) {
|
func (f *FileSystem) Stat(name string) (os.FileInfo, error) {
|
||||||
log.Println("FileSystem.Stat", name)
|
f.log.Debug("FileSystem.Stat", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
})
|
||||||
|
|
||||||
hdr, err := inventory.Stat(
|
hdr, err := inventory.Stat(
|
||||||
f.metadata,
|
f.metadata,
|
||||||
@@ -301,7 +337,7 @@ func (f *FileSystem) Stat(name string) (os.FileInfo, error) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewFileInfo(hdr), nil
|
return NewFileInfo(hdr, f.log), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) updateMetadata(hdr *tar.Header) error {
|
func (f *FileSystem) updateMetadata(hdr *tar.Header) error {
|
||||||
@@ -332,7 +368,9 @@ func (f *FileSystem) updateMetadata(hdr *tar.Header) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Chmod(name string, mode os.FileMode) error {
|
func (f *FileSystem) Chmod(name string, mode os.FileMode) error {
|
||||||
log.Println("FileSystem.Chmod", name, mode)
|
f.log.Debug("FileSystem.Chmod", map[string]interface{}{
|
||||||
|
"name": mode,
|
||||||
|
})
|
||||||
|
|
||||||
hdr, err := inventory.Stat(
|
hdr, err := inventory.Stat(
|
||||||
f.metadata,
|
f.metadata,
|
||||||
@@ -355,7 +393,11 @@ func (f *FileSystem) Chmod(name string, mode os.FileMode) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Chown(name string, uid, gid int) error {
|
func (f *FileSystem) Chown(name string, uid, gid int) error {
|
||||||
log.Println("FileSystem.Chown", name, uid, gid)
|
f.log.Debug("FileSystem.Chown", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
"uid": uid,
|
||||||
|
"gid": gid,
|
||||||
|
})
|
||||||
|
|
||||||
hdr, err := inventory.Stat(
|
hdr, err := inventory.Stat(
|
||||||
f.metadata,
|
f.metadata,
|
||||||
@@ -379,7 +421,11 @@ func (f *FileSystem) Chown(name string, uid, gid int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) Chtimes(name string, atime time.Time, mtime time.Time) error {
|
func (f *FileSystem) Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||||
log.Println("FileSystem.Chtimes", name, atime, mtime)
|
f.log.Debug("FileSystem.Chtimes", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
"atime": atime,
|
||||||
|
"mtime": mtime,
|
||||||
|
})
|
||||||
|
|
||||||
hdr, err := inventory.Stat(
|
hdr, err := inventory.Stat(
|
||||||
f.metadata,
|
f.metadata,
|
||||||
@@ -403,19 +449,26 @@ func (f *FileSystem) Chtimes(name string, atime time.Time, mtime time.Time) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) LstatIfPossible(name string) (os.FileInfo, bool, error) {
|
func (f *FileSystem) LstatIfPossible(name string) (os.FileInfo, bool, error) {
|
||||||
log.Println("FileSystem.LstatIfPossible", name)
|
f.log.Debug("FileSystem.LstatIfPossible", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
})
|
||||||
|
|
||||||
panic(ErrNotImplemented)
|
panic(ErrNotImplemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) SymlinkIfPossible(oldname, newname string) error {
|
func (f *FileSystem) SymlinkIfPossible(oldname, newname string) error {
|
||||||
log.Println("FileSystem.SymlinkIfPossible", oldname, newname)
|
f.log.Debug("FileSystem.SymlinkIfPossible", map[string]interface{}{
|
||||||
|
"oldname": oldname,
|
||||||
|
"newname": newname,
|
||||||
|
})
|
||||||
|
|
||||||
panic(ErrNotImplemented)
|
panic(ErrNotImplemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileSystem) ReadlinkIfPossible(name string) (string, error) {
|
func (f *FileSystem) ReadlinkIfPossible(name string) (string, error) {
|
||||||
log.Println("FileSystem.ReadlinkIfPossible", name)
|
f.log.Debug("FileSystem.ReadlinkIfPossible", map[string]interface{}{
|
||||||
|
"name": name,
|
||||||
|
})
|
||||||
|
|
||||||
panic(ErrNotImplemented)
|
panic(ErrNotImplemented)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package ftp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
golog "github.com/fclairamb/go-log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Logger struct{}
|
|
||||||
|
|
||||||
func (l Logger) Debug(event string, keyvals ...interface{}) {
|
|
||||||
log.Println(event, keyvals)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Logger) Info(event string, keyvals ...interface{}) {
|
|
||||||
log.Println(event, keyvals)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Logger) Warn(event string, keyvals ...interface{}) {
|
|
||||||
log.Println(event, keyvals)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Logger) Error(event string, keyvals ...interface{}) {
|
|
||||||
log.Println(event, keyvals)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Logger) With(keyvals ...interface{}) golog.Logger {
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
@@ -27,15 +27,15 @@ func headerEventToCSV(event *config.HeaderEvent) []string {
|
|||||||
return append([]string{event.Type, fmt.Sprintf("%v", event.Indexed)}, headerToCSV(event.Header)...)
|
return append([]string{event.Type, fmt.Sprintf("%v", event.Indexed)}, headerToCSV(event.Header)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Logger struct {
|
type CSVLogger struct {
|
||||||
n int
|
n int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLogger() *Logger {
|
func NewCSVLogger() *CSVLogger {
|
||||||
return &Logger{}
|
return &CSVLogger{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) PrintHeader(hdr *models.Header) {
|
func (l *CSVLogger) PrintHeader(hdr *models.Header) {
|
||||||
w := csv.NewWriter(os.Stdout)
|
w := csv.NewWriter(os.Stdout)
|
||||||
|
|
||||||
if l.n <= 0 {
|
if l.n <= 0 {
|
||||||
@@ -49,7 +49,7 @@ func (l *Logger) PrintHeader(hdr *models.Header) {
|
|||||||
l.n++
|
l.n++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) PrintHeaderEvent(event *config.HeaderEvent) {
|
func (l *CSVLogger) PrintHeaderEvent(event *config.HeaderEvent) {
|
||||||
w := csv.NewWriter(os.Stdout)
|
w := csv.NewWriter(os.Stdout)
|
||||||
|
|
||||||
if l.n <= 0 {
|
if l.n <= 0 {
|
||||||
|
|||||||
37
internal/logging/json.go
Normal file
37
internal/logging/json.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
golog "github.com/fclairamb/go-log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type JSONLogger struct{}
|
||||||
|
|
||||||
|
func NewJSONLogger() *JSONLogger {
|
||||||
|
return &JSONLogger{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l JSONLogger) Trace(event string, keyvals ...interface{}) {
|
||||||
|
log.Println("TRACE", event, keyvals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l JSONLogger) Debug(event string, keyvals ...interface{}) {
|
||||||
|
log.Println("DEBUG", event, keyvals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l JSONLogger) Info(event string, keyvals ...interface{}) {
|
||||||
|
log.Println("INFO", event, keyvals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l JSONLogger) Warn(event string, keyvals ...interface{}) {
|
||||||
|
log.Println("WARN", event, keyvals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l JSONLogger) Error(event string, keyvals ...interface{}) {
|
||||||
|
log.Println("ERROR", event, keyvals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l JSONLogger) With(keyvals ...interface{}) golog.Logger {
|
||||||
|
return l
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user