[VOL-2538] Logging - Implement dynamic log levels in ofagent
Change-Id: I9582230d9d3c34ea84339fddf2b2f3b3d2804808
diff --git a/cmd/ofagent/config.go b/cmd/ofagent/config.go
index 1ced4e8..0147cad 100644
--- a/cmd/ofagent/config.go
+++ b/cmd/ofagent/config.go
@@ -17,6 +17,7 @@
import (
"flag"
+ "os"
"time"
)
@@ -32,6 +33,11 @@
DeviceListRefreshInterval time.Duration
ConnectionRetryDelay time.Duration
ConnectionMaxRetries int
+ KVStoreType string
+ KVStoreTimeout int // in seconds
+ KVStoreHost string
+ KVStorePort int
+ InstanceID string
}
func parseCommandLineArguments() (*Config, error) {
@@ -69,14 +75,6 @@
"P",
":8080",
"(short) address and port on which to listen for k8s live and ready probe requests")
- flag.StringVar(&(config.LogLevel),
- "loglevel",
- "WARN",
- "initial log level setting, overriden by any value set in configuration store")
- flag.StringVar(&(config.LogLevel),
- "L",
- "WARN",
- "(short) initial log level setting, overriden by any value set in configuration store")
flag.StringVar(&(config.CpuProfile),
"cpuprofile",
"",
@@ -109,6 +107,26 @@
"device-refresh-interval",
1*time.Minute,
"interval between attempts to synchronize devices from voltha to ofagent")
+ flag.StringVar(&(config.KVStoreType), "kv_store_type", "etcd", "KV store type")
+
+ flag.IntVar(&(config.KVStoreTimeout), "kv_store_request_timeout", 5, "The default timeout when making a kv store request")
+
+ flag.StringVar(&(config.KVStoreHost), "kv_store_host", "voltha-etcd-cluster-client.voltha.svc.cluster.local", "KV store host")
+
+ flag.IntVar(&(config.KVStorePort), "kv_store_port", 2379, "KV store port")
+
+ flag.StringVar(&(config.LogLevel), "log_level", "DEBUG", "Log level")
+
+ containerName := getContainerInfo()
+ if len(containerName) > 0 {
+ config.InstanceID = containerName
+ } else {
+ config.InstanceID = "openFlowAgent001"
+ }
return &config, nil
}
+
+func getContainerInfo() string {
+ return os.Getenv("HOSTNAME")
+}
diff --git a/cmd/ofagent/main.go b/cmd/ofagent/main.go
index b0d107b..b2c9631 100644
--- a/cmd/ofagent/main.go
+++ b/cmd/ofagent/main.go
@@ -21,11 +21,13 @@
"flag"
"fmt"
"github.com/opencord/ofagent-go/internal/pkg/ofagent"
+ conf "github.com/opencord/voltha-lib-go/v3/pkg/config"
+ "github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-lib-go/v3/pkg/probe"
"github.com/opencord/voltha-lib-go/v3/pkg/version"
"os"
- "strings"
+ "strconv"
)
func printBanner() {
@@ -49,6 +51,31 @@
}
}
+func setLogConfig(ctx context.Context, kvStoreHost, kvStoreType string, kvStorePort, kvStoreTimeout int) (kvstore.Client, error) {
+ client, err := kvstore.NewEtcdClient(kvStoreHost+":"+strconv.Itoa(kvStorePort), kvStoreTimeout)
+ if err != nil {
+ return nil, err
+ }
+
+ cm := conf.NewConfigManager(client, kvStoreType, kvStoreHost, kvStorePort, kvStoreTimeout)
+ go conf.ProcessLogConfigChange(cm, ctx)
+ return client, nil
+}
+
+func stop(ctx context.Context, kvClient kvstore.Client) {
+
+ // Cleanup - applies only if we had a kvClient
+ if kvClient != nil {
+ // Release all reservations
+ if err := kvClient.ReleaseAllReservations(ctx); err != nil {
+ log.Infow("fail-to-release-all-reservations", log.Fields{"error": err})
+ }
+ // Close the DB connection
+ kvClient.Close()
+ }
+
+}
+
func main() {
config, _ := parseCommandLineArguments()
@@ -63,57 +90,31 @@
printBanner()
}
- if err := log.SetLogLevel(log.DebugLevel); err != nil {
- log.Errorw("set-log-level", log.Fields{
- "level": log.DebugLevel,
- "error": err})
- }
- if _, err := log.SetDefaultLogger(log.JSON, log.DebugLevel, log.Fields{"component": "ofagent"}); err != nil {
- log.Errorw("set-default-log-level", log.Fields{
- "level": log.DebugLevel,
- "error": err})
+ // Setup logging
+ logLevel, err := log.StringToLogLevel(config.LogLevel)
+ if err != nil {
+ log.Fatalf("Cannot setup logging, %s", err)
}
- var logLevel int
- switch strings.ToLower(config.LogLevel) {
- case "fatal":
- logLevel = log.FatalLevel
- case "error":
- logLevel = log.ErrorLevel
- case "warn":
- logLevel = log.WarnLevel
- case "info":
- logLevel = log.InfoLevel
- case "debug":
- logLevel = log.DebugLevel
- default:
- log.Warn("unrecognized-log-level",
- log.Fields{
- "msg": "Unrecognized log level setting defaulting to 'WARN'",
- "component": "ofagent",
- "value": config.LogLevel,
- })
- config.LogLevel = "WARN"
- logLevel = log.WarnLevel
+ // Setup default logger - applies for packages that do not have specific logger set
+ if _, err := log.SetDefaultLogger(log.JSON, logLevel, log.Fields{"instanceId": config.InstanceID}); err != nil {
+ log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
}
- if _, err := log.SetDefaultLogger(log.JSON, logLevel, log.Fields{"component": "ofagent"}); err != nil {
- log.Errorw("set-default-log-level", log.Fields{
- "level": logLevel,
- "error": err})
+ // Update all loggers (provisionned via init) with a common field
+ if err := log.UpdateAllLoggers(log.Fields{"instanceId": config.InstanceID}); err != nil {
+ log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
}
+
log.SetAllLogLevel(logLevel)
- log.Infow("ofagent-startup-configuration",
- log.Fields{
- "configuration": fmt.Sprintf("%+v", *config),
- })
-
- _, err := log.AddPackage(log.JSON, logLevel, nil)
- if err != nil {
- log.Errorw("unable-to-register-package-to-the-log-map", log.Fields{"error": err})
- }
+ defer func() {
+ err := log.CleanUp()
+ if err != nil {
+ log.Errorw("unable-to-flush-any-buffered-log-entries", log.Fields{"error": err})
+ }
+ }()
/*
* Create and start the liveness and readiness container management probes. This
@@ -129,6 +130,11 @@
*/
ctx := context.WithValue(context.Background(), probe.ProbeContextKey, p)
+ client, err := setLogConfig(ctx, config.KVStoreHost, config.KVStoreType, config.KVStorePort, config.KVStoreTimeout)
+ if err != nil {
+ log.Warnw("unable-to-create-kvstore-client", log.Fields{"error": err})
+ }
+
ofa, err := ofagent.NewOFAgent(&ofagent.OFAgent{
OFControllerEndPoint: config.OFControllerEndPoint,
VolthaApiEndPoint: config.VolthaApiEndPoint,
@@ -142,4 +148,5 @@
"error": err})
}
ofa.Run(ctx)
+ stop(ctx, client)
}