Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structured logging #275

Merged
merged 1 commit into from
Sep 7, 2022
Merged

Structured logging #275

merged 1 commit into from
Sep 7, 2022

Conversation

uablrek
Copy link
Contributor

@uablrek uablrek commented Aug 31, 2022

Description

Structured logging a'la K8s, go-logr/logr

Issue link

#253

Checklist

  • Purpose
    • Bug fix
    • New functionality
    • Documentation
    • Refactoring
    • CI
  • Test
    • Unit test
    • E2E Test
    • Tested manually
  • Introduce a breaking change
    • Yes (description required)
    • No
  • Introduce changes in the Operator
    • Yes (description required)
    • No

Sorry, something went wrong.

@uablrek uablrek mentioned this pull request Aug 31, 2022
12 tasks
@uablrek
Copy link
Contributor Author

uablrek commented Aug 31, 2022

To test structured logs, switch to this branch and build ipam, then start KinD and do;

kubectl logs -n red ipam-trench-a-0 | jq

Snip;

{
  "severity": "info",
  "timestamp": "2022-08-31T15:11:25.294+00:00",
  "service_id": "Meridio-ipam",
  "message": "Configuration read",
  "version": "1.1.0",
  "extra_data": {
    "config": {
      "Port": 7777,
      "Datasource": "/run/ipam/data/registry.db",
      "TrenchName": "trench-a",
      "NSPService": "nsp-service-trench-a:7778",
      "PrefixIPv4": "172.16.0.0/16",
      "ConduitPrefixLengthIPv4": 20,
      "NodePrefixLengthIPv4": 24,
      "PrefixIPv6": "fd00::/48",
      "ConduitPrefixLengthIPv6": 56,
      "NodePrefixLengthIPv6": 64,
      "IPFamily": "dualstack",
      "LogLevel": "DEBUG"
    }
  }
}
{
  "severity": "debug",
  "timestamp": "2022-08-31T15:11:25.295+00:00",
  "service_id": "Meridio-ipam",
  "message": "Health server: Register subservices",
  "version": "1.1.0",
  "extra_data": {
    "probeSvc": "Readiness",
    "services": [
      "NSPCli",
      "IPAM"
    ]
  }
}

@uablrek uablrek requested review from zolug and LionelJouin August 31, 2022 16:39
@uablrek uablrek self-assigned this Aug 31, 2022
@uablrek uablrek added the kind/enhancement New feature or request label Aug 31, 2022
@uablrek
Copy link
Contributor Author

uablrek commented Sep 3, 2022

Shall we make the ADP format the only one?

My approach was that Meridio is an open-source project first and Ericsson second. But let's be realistic, Meridio will be used only by Ericsson for a long time. As such we can make the Ericsson format the only format and add different formats later if needed. The current implementation can be seen as a PoC that different formats can be supported.

@uablrek
Copy link
Contributor Author

uablrek commented Sep 3, 2022

Shall we have a global logger?

I have kind of gone all-in on the go-logr/logr concepts (except for Fatal()). E.g. the WithValues() function can be used to pass adapted loggers down the food-chain. But the individual parts of Meridio are fairly small (at least compared to K8s) so a more pragmatic approach may be acceptable. For instance;

// New() is supposed to be called once and will also set the global Logger
// (multiple calls to New() are allowed but will over-write the global Logger)
logger := log.New("Meridio-ipam", config.LogLevel)
// The global logger can be used anywhere
log.Logger.Info("Printed by the global logger")

N.B. the intended way of using go-logr/logr is still possible, but it is not enforced.

@uablrek
Copy link
Contributor Author

uablrek commented Sep 3, 2022

The latest commit implements an NSM logger, used as (see load-balancer/main.go);

	// Work-around for hard-codes logrus dependency in NSM
	if config.LogLevel == "TRACE" {
		nsmlog.EnableTracing(true)
		logrus.SetLevel(logrus.TraceLevel)
	}
	logger.Info("NSM trace", "enabled", nsmlog.IsTracingEnabled())
	ctx = nsmlog.WithLog(ctx, log.NSMLogger(logger)) // allow NSM logs

but trace logs are not formatted because of a NSM log issue.

@uablrek
Copy link
Contributor Author

uablrek commented Sep 5, 2022

Some thoughts about "subsystems"

These should be used with care (if used at all). It does not help any one (developers or users) to just make them up. IMO the only two real subsytems that make sense are bird and nfqlb. If we catch log printouts from those and use a "logger" to re-emit them in our choosen format (as we should IMO), then a "subsystem" entry shall be used.

Update

NSM is also a subsystem of course! When the NSM log issue is solved NSM logs may look something like this;

{
  "severity": "info",
  "timestamp": "2022-09-06T12:47:19.258+02:00",
  "service_id": "NSMLogger-info",
  "message": "Object",
  "version": "1.0.0",
  "extra_data": {
    "subsystem": "NSM",
    "44": "Key is an int"
  }
}

@uablrek
Copy link
Contributor Author

uablrek commented Sep 6, 2022

An example structured log from a load-balancer-a on KinD setup for Meridio e2e; load-balancer-json.log

Formatted with jq.

@uablrek
Copy link
Contributor Author

uablrek commented Sep 7, 2022

I have removed all conversion to structured logging in Meridio code and made this PR a pure add-on.

I would like a fast review/approval to allow independent and parallel conversion to structured logging of Meridio code.

@uablrek
Copy link
Contributor Author

uablrek commented Sep 7, 2022

The usage of the log package is removed from this PR but an example output can be found in #275 (comment).

@@ -0,0 +1,102 @@
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Copyright

panic(fmt.Sprintf("Can't create a zap logger (%v)?", err))
}
return zapr.NewLogger(z.With(
zap.String("version", "1.0.0"), zap.Namespace("extra_data")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be the Meridio Version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's the version of the ADP format. It is required according to the ADP format spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  "required": [
    "version",
    "timestamp",
    "severity",
    "service_id",
    "message"
  ]

go.mod Outdated
@@ -5,6 +5,8 @@ go 1.19
require (
github.com/antonfisher/nested-logrus-formatter v1.3.1
github.com/edwarnicke/grpcfd v1.1.2
github.com/go-logr/logr v1.2.3
github.com/go-logr/zapr v1.2.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a new release 1.2.3 https://github.com/go-logr/zapr/releases

go.mod Outdated
@@ -21,6 +23,7 @@ require (
github.com/stretchr/testify v1.8.0
github.com/vishvananda/netlink v1.2.1-beta.2.0.20220630165224-c591ada0fb2b
go.uber.org/goleak v1.1.12
go.uber.org/zap v1.19.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a new release 1.23.0 https://github.com/uber-go/zap/releases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have just done go mod tidy. How goes go select the versions?

Copy link
Member

@LionelJouin LionelJouin Sep 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use go mod edit -require go.uber.org/[email protected] (or change manually in the go.mod) then go mod tidy, but otherwise I have no idea how go selects the versions (Maybe it depends on the go version you have installed locally?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I edited go.mod

docs/logging.md Outdated
```

There is no defined "trace" level in output so both trace and debug
messages will be have severity "debug". The level filtering is still valid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
messages will be have severity "debug". The level filtering is still valid
messages will have severity "debug". The level filtering is still valid

docs/logging.md Outdated

There is no defined "trace" level in output so both trace and debug
messages will be have severity "debug". The level filtering is still valid
though, trace messages are suspressed unless TRACE level is set.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
though, trace messages are suspressed unless TRACE level is set.
though, trace messages are suppressed unless TRACE level is set.

@uablrek uablrek merged commit e15c490 into master Sep 7, 2022
@uablrek uablrek deleted the loggingV2 branch September 7, 2022 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

2 participants