github.com/Axway/agent-sdk@v1.1.101/pkg/config/logconfig.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "strings" 7 8 "github.com/Axway/agent-sdk/pkg/cmd/properties" 9 "github.com/Axway/agent-sdk/pkg/util/log" 10 "github.com/elastic/beats/v7/libbeat/cfgfile" 11 "github.com/elastic/beats/v7/libbeat/common" 12 "github.com/sirupsen/logrus" 13 ) 14 15 // LogConfig - Interface for logging config 16 type LogConfig interface { 17 SetLevel(level string) 18 GetMetricConfig() LogFileConfiguration 19 GetUsageConfig() LogFileConfiguration 20 } 21 22 // LogConfiguration - 23 type LogConfiguration struct { 24 LogConfig 25 Level string `config:"level"` 26 Format string `config:"format"` 27 Output string `config:"output"` 28 File LogFileConfiguration `config:"file"` 29 MetricFile LogFileConfiguration `config:"metricfile"` 30 UsageFile LogFileConfiguration `config:"usagefile"` 31 MaskedValues string `config:"maskedvalues"` 32 } 33 34 func (l *LogConfiguration) setupLogger(agentType AgentType) error { 35 return log.GlobalLoggerConfig.Level(l.Level). 36 Format(l.Format). 37 Output(l.Output). 38 Filename(l.File.Name). 39 Path(l.File.Path). 40 MaxSize(l.File.MaxSize). 41 MaxBackups(l.File.MaxBackups). 42 MaxAge(l.File.MaxAge). 43 Metrics(agentType == TraceabilityAgent && l.MetricFile.Enabled). 44 MetricFilename(l.MetricFile.Name). 45 MaxMetricSize(l.MetricFile.MaxSize). 46 MaxMetricBackups(l.MetricFile.MaxBackups). 47 MaxMetricAge(l.MetricFile.MaxAge). 48 Usage(agentType == TraceabilityAgent && l.UsageFile.Enabled). 49 UsageFilename(l.UsageFile.Name). 50 MaxUsageSize(l.UsageFile.MaxSize). 51 MaxUsageBackups(l.UsageFile.MaxBackups). 52 MaxUsageAge(l.UsageFile.MaxAge). 53 Apply() 54 } 55 56 func (l *LogConfiguration) GetMetricConfig() LogFileConfiguration { 57 return l.MetricFile 58 } 59 60 func (l *LogConfiguration) GetUsagefileConfig() LogFileConfiguration { 61 return l.UsageFile 62 } 63 64 // LogFileConfiguration - setup the logging configuration for file output 65 type LogFileConfiguration struct { 66 Enabled bool `config:"enable"` 67 Name string `config:"name"` 68 Path string `config:"path"` 69 MaxSize int `config:"rotateeverybytes"` 70 MaxAge int `config:"cleanbackups"` 71 MaxBackups int `config:"keepfiles"` 72 } 73 74 const ( 75 pathLogLevel = "log.level" 76 pathLogFormat = "log.format" 77 pathLogOutput = "log.output" 78 pathLogMaskedValues = "log.maskedValues" 79 pathLogFileName = "log.file.name" 80 pathLogFilePath = "log.file.path" 81 pathLogFileMaxSize = "log.file.rotateeverybytes" 82 pathLogFileMaxAge = "log.file.cleanbackups" 83 pathLogFileMaxBackups = "log.file.keepfiles" 84 pathLogMetricsFileEnabled = "log.metricfile.enabled" 85 pathLogMetricsFileName = "log.metricfile.name" 86 pathLogMetricsFileMaxSize = "log.metricfile.rotateeverybytes" 87 pathLogMetricsFileMaxAge = "log.metricfile.cleanbackups" 88 pathLogMetricsFileMaxBackups = "log.metricfile.keepfiles" 89 pathLogUsageFileEnabled = "log.usagefile.enabled" 90 pathLogUsageFileName = "log.usagefile.name" 91 pathLogUsageFileMaxSize = "log.usagefile.rotateeverybytes" 92 pathLogUsageFileMaxAge = "log.usagefile.cleanbackupsevery" 93 pathLogUsageFileMaxBackups = "log.usagefile.keepfiles" 94 ) 95 96 // AddLogConfigProperties - Adds the command properties needed for Log Config 97 func AddLogConfigProperties(props properties.Properties, defaultFileName string) { 98 props.AddStringProperty(pathLogLevel, "info", "Log level (trace, debug, info, warn, error)") 99 props.AddStringProperty(pathLogFormat, "json", "Log format (json, line)") 100 props.AddStringProperty(pathLogOutput, "stdout", "Log output type (stdout, file, both)") 101 props.AddStringProperty(pathLogMaskedValues, "", "List of key words in the config to be masked (e.g. pwd, password, secret, key") 102 103 // Log file options 104 props.AddStringProperty(pathLogFileName, defaultFileName, "Name of the log files") 105 props.AddStringProperty(pathLogFilePath, "logs", "Log file path if output type is file or both") 106 props.AddIntProperty(pathLogFileMaxSize, 10485760, "The maximum size of a log file, in bytes (default: 10485760 - 10 MB)") 107 props.AddIntProperty(pathLogFileMaxAge, 0, "The maximum number of days, 24 hour periods, to keep the log file backups") 108 props.AddIntProperty(pathLogFileMaxBackups, 7, "The maximum number of backups to keep of log files (default: 7)") 109 } 110 111 // AddMetricLogConfigProperties - Adds the command properties needed for Log Config 112 func AddMetricLogConfigProperties(props properties.Properties, agentType AgentType) { 113 if agentType == DiscoveryAgent { 114 return 115 } 116 // Metric log file options 117 props.AddBoolProperty(pathLogMetricsFileEnabled, true, "Set to false to disable metrics file logging") 118 props.AddStringProperty(pathLogMetricsFileName, "metrics.log", "Name of the metric log files") 119 props.AddIntProperty(pathLogMetricsFileMaxSize, 10485760, "The maximum size of a metrics log file, in bytes (default: 10485760 - 10 MB)") 120 props.AddIntProperty(pathLogMetricsFileMaxAge, 0, "The maximum number of days, 24 hour periods, to keep the metrics log file backups") 121 props.AddIntProperty(pathLogMetricsFileMaxBackups, 0, "The maximum number of backups to keep of metrics log files (default: unlimited)") 122 } 123 124 func AddUsageConfigProperties(props properties.Properties, agentType AgentType) { 125 if agentType == DiscoveryAgent { 126 return 127 } 128 129 props.AddBoolProperty(pathLogUsageFileEnabled, true, "Set to false to disable usage file logging") 130 props.AddStringProperty(pathLogUsageFileName, "usage.log", "Name of the usage log files") 131 props.AddIntProperty(pathLogUsageFileMaxSize, 10485760, "The maximum size of a usage log file, in bytes (default: 10485760 - 10 MB)") 132 props.AddIntProperty(pathLogUsageFileMaxAge, 365, "The maximum number of days, 24 hour periods, to keep the usage log file backups") 133 props.AddIntProperty(pathLogUsageFileMaxBackups, 0, "The maximum number of backups to keep of metrics log files (default: unlimited)") 134 } 135 136 // ParseAndSetupLogConfig - Parses the Log Config and setups the logger 137 func ParseAndSetupLogConfig(props properties.Properties, agentType AgentType) (LogConfig, error) { 138 cfg := &LogConfiguration{ 139 Level: props.StringPropertyValue(pathLogLevel), 140 Format: props.StringPropertyValue(pathLogFormat), 141 Output: props.StringPropertyValue(pathLogOutput), 142 MaskedValues: props.StringPropertyValue(pathLogMaskedValues), 143 File: LogFileConfiguration{ 144 Name: props.StringPropertyValue(pathLogFileName), 145 Path: props.StringPropertyValue(pathLogFilePath), 146 MaxSize: props.IntPropertyValue(pathLogFileMaxSize), 147 MaxBackups: props.IntPropertyValue(pathLogFileMaxBackups), 148 MaxAge: props.IntPropertyValue(pathLogFileMaxAge), 149 }, 150 } 151 152 if agentType == TraceabilityAgent { 153 cfg.MetricFile = LogFileConfiguration{ 154 Enabled: props.BoolPropertyValue(pathLogMetricsFileEnabled), 155 Name: props.StringPropertyValue(pathLogMetricsFileName), 156 Path: filepath.Join(cfg.File.Path, "metrics"), 157 MaxSize: props.IntPropertyValue(pathLogMetricsFileMaxSize), 158 MaxBackups: props.IntPropertyValue(pathLogMetricsFileMaxBackups), 159 MaxAge: props.IntPropertyValue(pathLogMetricsFileMaxAge), 160 } 161 cfg.UsageFile = LogFileConfiguration{ 162 Enabled: props.BoolPropertyValue(pathLogUsageFileEnabled), 163 Name: props.StringPropertyValue(pathLogUsageFileName), 164 Path: filepath.Join(cfg.File.Path, "usage"), 165 MaxSize: props.IntPropertyValue(pathLogUsageFileMaxSize), 166 MaxBackups: props.IntPropertyValue(pathLogUsageFileMaxBackups), 167 MaxAge: props.IntPropertyValue(pathLogUsageFileMaxAge), 168 } 169 } 170 171 // Only attempt to mask values if the key maskValues AND key words for maskValues exist 172 if cfg.MaskedValues != "" { 173 props.MaskValues(cfg.MaskedValues) 174 } 175 176 return cfg, cfg.setupLogger(agentType) 177 } 178 179 const ( 180 logLevelYAMLPath = "logging.level" 181 logJSONYAMLPath = "logging.json" 182 logSTDERRYAMLPath = "logging.to_stderr" 183 logFileYAMLPath = "logging.to_files" 184 logFilePermissionsPath = "logging.files.permissions" 185 ) 186 187 // LogConfigOverrides - override the filebeat config options 188 func LogConfigOverrides() []cfgfile.ConditionalOverride { 189 overrides := make([]cfgfile.ConditionalOverride, 0) 190 overrides = setLogLevel(overrides) 191 return overrideLogLevel(overrides) 192 } 193 194 func setLogLevel(overrides []cfgfile.ConditionalOverride) []cfgfile.ConditionalOverride { 195 // Set level to info 196 overrides = append(overrides, cfgfile.ConditionalOverride{ 197 Check: func(cfg *common.Config) bool { 198 aliasKeyPrefix := properties.GetAliasKeyPrefix() 199 output, _ := cfg.String(fmt.Sprintf("%s.%s", aliasKeyPrefix, pathLogLevel), 0) 200 level, err := logrus.ParseLevel(output) 201 if err == nil && level == logrus.InfoLevel { 202 return true 203 } 204 return false 205 }, 206 Config: common.MustNewConfigFrom(map[string]interface{}{ 207 logLevelYAMLPath: "info", 208 }), 209 }) 210 211 // Set level to warn 212 overrides = append(overrides, cfgfile.ConditionalOverride{ 213 Check: func(cfg *common.Config) bool { 214 aliasKeyPrefix := properties.GetAliasKeyPrefix() 215 output, _ := cfg.String(fmt.Sprintf("%s.%s", aliasKeyPrefix, pathLogLevel), 0) 216 level, err := logrus.ParseLevel(output) 217 if err == nil && level == logrus.WarnLevel { 218 return true 219 } 220 return false 221 }, 222 Config: common.MustNewConfigFrom(map[string]interface{}{ 223 logLevelYAMLPath: "warn", 224 }), 225 }) 226 227 // Set level to error 228 overrides = append(overrides, cfgfile.ConditionalOverride{ 229 Check: func(cfg *common.Config) bool { 230 aliasKeyPrefix := properties.GetAliasKeyPrefix() 231 output, _ := cfg.String(fmt.Sprintf("%s.%s", aliasKeyPrefix, pathLogLevel), 0) 232 level, err := logrus.ParseLevel(output) 233 if err == nil && level == logrus.ErrorLevel { 234 return true 235 } 236 return false 237 }, 238 Config: common.MustNewConfigFrom(map[string]interface{}{ 239 logLevelYAMLPath: "error", 240 }), 241 }) 242 243 return overrides 244 } 245 246 func overrideLogLevel(overrides []cfgfile.ConditionalOverride) []cfgfile.ConditionalOverride { 247 // Override the level to debug, if trace or debug 248 overrides = append(overrides, cfgfile.ConditionalOverride{ 249 Check: func(cfg *common.Config) bool { 250 aliasKeyPrefix := properties.GetAliasKeyPrefix() 251 output, _ := cfg.String(fmt.Sprintf("%s.%s", aliasKeyPrefix, pathLogLevel), 0) 252 level, err := logrus.ParseLevel(output) 253 if err == nil && (level == logrus.TraceLevel || level == logrus.DebugLevel) { 254 return true 255 } 256 return false 257 }, 258 Config: common.MustNewConfigFrom(map[string]interface{}{ 259 logLevelYAMLPath: "debug", 260 }), 261 }) 262 263 // Override the log output format 264 overrides = append(overrides, cfgfile.ConditionalOverride{ 265 Check: func(cfg *common.Config) bool { 266 aliasKeyPrefix := properties.GetAliasKeyPrefix() 267 output, _ := cfg.String(fmt.Sprintf("%s.%s", aliasKeyPrefix, pathLogFormat), 0) 268 return strings.ToLower(output) == "json" 269 }, 270 Config: common.MustNewConfigFrom(map[string]interface{}{ 271 logJSONYAMLPath: true, 272 }), 273 }) 274 275 // Override the log output stream 276 overrides = append(overrides, cfgfile.ConditionalOverride{ 277 Check: func(cfg *common.Config) bool { 278 aliasKeyPrefix := properties.GetAliasKeyPrefix() 279 output, _ := cfg.String(fmt.Sprintf("%s.%s", aliasKeyPrefix, pathLogOutput), 0) 280 return strings.ToLower(output) == "stdout" 281 }, 282 Config: common.MustNewConfigFrom(map[string]interface{}{ 283 logSTDERRYAMLPath: true, 284 logFileYAMLPath: false, 285 }), 286 }) 287 288 // Override the log output to file 289 overrides = append(overrides, cfgfile.ConditionalOverride{ 290 Check: func(cfg *common.Config) bool { 291 aliasKeyPrefix := properties.GetAliasKeyPrefix() 292 output, _ := cfg.String(fmt.Sprintf("%s.%s", aliasKeyPrefix, pathLogOutput), 0) 293 if strings.ToLower(output) == "file" || strings.ToLower(output) == "both" { 294 if strings.ToLower(output) == "both" { 295 log.Warn("Traceability agent can only log to one output type, setting to file output") 296 } 297 return true 298 } 299 return false 300 }, 301 Config: common.MustNewConfigFrom(map[string]interface{}{ 302 logFileYAMLPath: true, 303 logSTDERRYAMLPath: false, 304 logFilePermissionsPath: "0600", 305 }), 306 }) 307 308 return overrides 309 }