mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
Logs JSON output.
This commit is contained in:
parent
f32e7e7075
commit
d108343ced
112
cmd/root.go
112
cmd/root.go
@ -34,49 +34,10 @@ func init() {
|
|||||||
rootConfig := config.Root{}
|
rootConfig := config.Root{}
|
||||||
|
|
||||||
cobra.OnInitialize(func() {
|
cobra.OnInitialize(func() {
|
||||||
//////
|
|
||||||
// logs
|
|
||||||
//////
|
|
||||||
console := zerolog.ConsoleWriter{Out: os.Stdout}
|
|
||||||
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
|
||||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
|
||||||
|
|
||||||
logs := viper.GetBool("logs")
|
|
||||||
if !logs {
|
|
||||||
log.Logger = log.Output(console)
|
|
||||||
} else {
|
|
||||||
logsPath := filepath.Join(".", "logs")
|
|
||||||
if runtime.GOOS == "linux" {
|
|
||||||
logsPath = "/var/log/neko"
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(logsPath); os.IsNotExist(err) {
|
|
||||||
_ = os.Mkdir(logsPath, os.ModePerm)
|
|
||||||
}
|
|
||||||
|
|
||||||
latest := filepath.Join(logsPath, "neko-latest.log")
|
|
||||||
if _, err := os.Stat(latest); err == nil {
|
|
||||||
err = os.Rename(latest, filepath.Join(logsPath, "neko."+time.Now().Format("2006-01-02T15-04-05Z07-00")+".log"))
|
|
||||||
if err != nil {
|
|
||||||
log.Panic().Err(err).Msg("failed to rotate log file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logf, err := os.OpenFile(latest, os.O_RDWR|os.O_CREATE, 0666)
|
|
||||||
if err != nil {
|
|
||||||
log.Panic().Err(err).Msg("failed to create log file")
|
|
||||||
}
|
|
||||||
|
|
||||||
logger := diode.NewWriter(logf, 1000, 10*time.Millisecond, func(missed int) {
|
|
||||||
fmt.Printf("logger dropped %d messages", missed)
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Logger = log.Output(io.MultiWriter(console, logger))
|
|
||||||
}
|
|
||||||
|
|
||||||
//////
|
//////
|
||||||
// configs
|
// configs
|
||||||
//////
|
//////
|
||||||
|
|
||||||
config := viper.GetString("config") // Use config file from the flag.
|
config := viper.GetString("config") // Use config file from the flag.
|
||||||
if config == "" {
|
if config == "" {
|
||||||
config = os.Getenv("NEKO_CONFIG") // Use config file from the environment variable.
|
config = os.Getenv("NEKO_CONFIG") // Use config file from the environment variable.
|
||||||
@ -97,26 +58,81 @@ func init() {
|
|||||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
viper.AutomaticEnv() // read in environment variables that match
|
viper.AutomaticEnv() // read in environment variables that match
|
||||||
|
|
||||||
|
// read config values
|
||||||
err := viper.ReadInConfig()
|
err := viper.ReadInConfig()
|
||||||
if err != nil && config != "" {
|
if err != nil && config != "" {
|
||||||
log.Err(err)
|
panic("unable to read config file: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// get full config file path
|
// get full config file path
|
||||||
config = viper.ConfigFileUsed()
|
config = viper.ConfigFileUsed()
|
||||||
|
|
||||||
|
// set root config values
|
||||||
|
rootConfig.Set()
|
||||||
|
|
||||||
//////
|
//////
|
||||||
// debug
|
// logs
|
||||||
//////
|
//////
|
||||||
debug := viper.GetBool("debug")
|
var logWriter io.Writer
|
||||||
if debug {
|
|
||||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
// log to a directory instead of stderr
|
||||||
|
if rootConfig.LogDir != "" {
|
||||||
|
if _, err := os.Stat(rootConfig.LogDir); os.IsNotExist(err) {
|
||||||
|
_ = os.Mkdir(rootConfig.LogDir, os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
|
latest := filepath.Join(rootConfig.LogDir, "neko-latest.log")
|
||||||
|
if _, err := os.Stat(latest); err == nil {
|
||||||
|
err = os.Rename(latest, filepath.Join(rootConfig.LogDir, "neko."+time.Now().Format("2006-01-02T15-04-05Z07-00")+".log"))
|
||||||
|
if err != nil {
|
||||||
|
panic("failed to rotate log file: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logf, err := os.OpenFile(latest, os.O_RDWR|os.O_CREATE, 0666)
|
||||||
|
if err != nil {
|
||||||
|
panic("failed to open log file: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
logWriter = diode.NewWriter(logf, 1000, 10*time.Millisecond, func(missed int) {
|
||||||
|
fmt.Printf("logger dropped %d messages", missed)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
logWriter = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
// log console output instead of json
|
||||||
|
if !rootConfig.LogJson {
|
||||||
|
logWriter = zerolog.ConsoleWriter{
|
||||||
|
Out: logWriter,
|
||||||
|
NoColor: rootConfig.LogNocolor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save new logger output
|
||||||
|
log.Logger = log.Output(logWriter)
|
||||||
|
|
||||||
|
// set custom log level
|
||||||
|
if rootConfig.LogLevel != zerolog.NoLevel {
|
||||||
|
zerolog.SetGlobalLevel(rootConfig.LogLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set custom log tiem format
|
||||||
|
if rootConfig.LogTime != "" {
|
||||||
|
zerolog.TimeFieldFormat = rootConfig.LogTime
|
||||||
|
}
|
||||||
|
|
||||||
|
timeFormat := rootConfig.LogTime
|
||||||
|
if rootConfig.LogTime == zerolog.TimeFormatUnix {
|
||||||
|
timeFormat = "UNIX"
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := log.With().
|
logger := log.With().
|
||||||
Bool("debug", debug).
|
|
||||||
Bool("logs", logs).
|
|
||||||
Str("config", config).
|
Str("config", config).
|
||||||
|
Str("log-level", zerolog.GlobalLevel().String()).
|
||||||
|
Bool("log-json", rootConfig.LogJson).
|
||||||
|
Str("log-time", timeFormat).
|
||||||
|
Str("log-dir", rootConfig.LogDir).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
if config == "" {
|
if config == "" {
|
||||||
@ -128,8 +144,6 @@ func init() {
|
|||||||
logger.Info().Msg("preflight complete with config file")
|
logger.Info().Msg("preflight complete with config file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootConfig.Set()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := rootConfig.Init(root); err != nil {
|
if err := rootConfig.Init(root); err != nil {
|
||||||
|
@ -1,29 +1,58 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Root struct {
|
type Root struct {
|
||||||
Debug bool
|
|
||||||
Logs bool
|
|
||||||
Config string
|
Config string
|
||||||
|
|
||||||
|
LogLevel zerolog.Level
|
||||||
|
LogTime string
|
||||||
|
LogJson bool
|
||||||
|
LogNocolor bool
|
||||||
|
LogDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Root) Init(cmd *cobra.Command) error {
|
func (Root) Init(cmd *cobra.Command) error {
|
||||||
|
cmd.PersistentFlags().StringP("config", "c", "", "configuration file path")
|
||||||
|
if err := viper.BindPFlag("config", cmd.PersistentFlags().Lookup("config")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// just a shortcut
|
||||||
cmd.PersistentFlags().BoolP("debug", "d", false, "enable debug mode")
|
cmd.PersistentFlags().BoolP("debug", "d", false, "enable debug mode")
|
||||||
if err := viper.BindPFlag("debug", cmd.PersistentFlags().Lookup("debug")); err != nil {
|
if err := viper.BindPFlag("debug", cmd.PersistentFlags().Lookup("debug")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.PersistentFlags().BoolP("logs", "l", false, "save logs to file")
|
cmd.PersistentFlags().String("log.level", "info", "set log level (trace, debug, info, warn, error, fatal, panic, disabled)")
|
||||||
if err := viper.BindPFlag("logs", cmd.PersistentFlags().Lookup("logs")); err != nil {
|
if err := viper.BindPFlag("log.level", cmd.PersistentFlags().Lookup("log.level")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.PersistentFlags().StringP("config", "c", "", "configuration file path")
|
cmd.PersistentFlags().String("log.time", "unix", "time format used in logs (unix, unixms, unixmicro)")
|
||||||
if err := viper.BindPFlag("config", cmd.PersistentFlags().Lookup("config")); err != nil {
|
if err := viper.BindPFlag("log.time", cmd.PersistentFlags().Lookup("log.time")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().Bool("log.json", false, "logs in JSON format")
|
||||||
|
if err := viper.BindPFlag("log.json", cmd.PersistentFlags().Lookup("log.json")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().Bool("log.nocolor", false, "no ANSI colors in non-JSON output")
|
||||||
|
if err := viper.BindPFlag("log.nocolor", cmd.PersistentFlags().Lookup("log.nocolor")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().String("log.dir", "", "logging directory to store logs")
|
||||||
|
if err := viper.BindPFlag("log.dir", cmd.PersistentFlags().Lookup("log.dir")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +60,38 @@ func (Root) Init(cmd *cobra.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Root) Set() {
|
func (s *Root) Set() {
|
||||||
s.Logs = viper.GetBool("logs")
|
|
||||||
s.Debug = viper.GetBool("debug")
|
|
||||||
s.Config = viper.GetString("config")
|
s.Config = viper.GetString("config")
|
||||||
|
|
||||||
|
logLevel := viper.GetString("log.level")
|
||||||
|
level, err := zerolog.ParseLevel(logLevel)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Msgf("unknown log level %s", logLevel)
|
||||||
|
} else {
|
||||||
|
s.LogLevel = level
|
||||||
|
}
|
||||||
|
|
||||||
|
logTime := viper.GetString("log.time")
|
||||||
|
switch logTime {
|
||||||
|
case "unix":
|
||||||
|
s.LogTime = zerolog.TimeFormatUnix
|
||||||
|
case "unixms":
|
||||||
|
s.LogTime = zerolog.TimeFormatUnixMs
|
||||||
|
case "unixmicro":
|
||||||
|
s.LogTime = zerolog.TimeFormatUnixMicro
|
||||||
|
default:
|
||||||
|
log.Warn().Msgf("unknown log time %s", logTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.LogJson = viper.GetBool("log.json")
|
||||||
|
s.LogNocolor = viper.GetBool("log.nocolor")
|
||||||
|
s.LogDir = viper.GetString("log.dir")
|
||||||
|
|
||||||
|
if viper.GetBool("debug") && s.LogLevel != zerolog.TraceLevel {
|
||||||
|
s.LogLevel = zerolog.DebugLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
// support for NO_COLOR env variable: https://no-color.org/
|
||||||
|
if os.Getenv("NO_COLOR") != "" {
|
||||||
|
s.LogNocolor = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func (manager *WebSocketManagerCtx) Start() {
|
|||||||
|
|
||||||
manager.sessions.Broadcast(event.CONTROL_HOST, payload, nil)
|
manager.sessions.Broadcast(event.CONTROL_HOST, payload, nil)
|
||||||
|
|
||||||
manager.logger.Debug().
|
manager.logger.Info().
|
||||||
Bool("has_host", payload.HasHost).
|
Bool("has_host", payload.HasHost).
|
||||||
Str("host_id", payload.HostID).
|
Str("host_id", payload.HostID).
|
||||||
Msg("session host changed")
|
Msg("session host changed")
|
||||||
@ -117,7 +117,7 @@ func (manager *WebSocketManagerCtx) Start() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.logger.Debug().Msg("sync clipboard")
|
manager.logger.Info().Msg("sync clipboard")
|
||||||
|
|
||||||
data, err := manager.desktop.ClipboardGetText()
|
data, err := manager.desktop.ClipboardGetText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user