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

Migrate to zap logger #223

Merged
merged 13 commits into from
Aug 15, 2018
Merged

Migrate to zap logger #223

merged 13 commits into from
Aug 15, 2018

Conversation

prydie
Copy link
Contributor

@prydie prydie commented Jul 31, 2018

Migrates logging from to go.uber.org/zap from github.com/golang/glog and adds the following flags:

--log-level=debug  # control log level
--log-json  # output log as json
--logfile-path  # if provided reload
❯ dist/oci-cloud-controller-manager         \
    --kubeconfig=${KUBECONFIG}              \
    --cloud-config=${CLOUD_PROVIDER_CFG}    \
    --cluster-cidr=10.244.0.0/16            \
    --leader-elect-resource-lock=configmaps \
    --cloud-provider=oci                    \
    --log-json                              \
    --logfile-path="test.log" &
❯ head -n 1 test.log
{"level":"info","ts":"2018-07-31T09:54:33.504+0100","caller":"oci/ccm.go:220","msg":"Using raw configuration provider"}

@prydie
Copy link
Contributor Author

prydie commented Jul 31, 2018

@templecloud do you have any insight into why the e2e tests are failing (I've merged your branch and rebased on top)?

pkg/log/log.go Outdated
)

func init() {
flag.StringVar(&lvlString, "log-level", lvlString, "Adjusts the level of the logs that will be omitted.")
Copy link
Member

Choose a reason for hiding this comment

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

This can be cleaned up.

var (
	lvl     = zapcore.InfoLevel
	logJSON = true
	config  *zap.Config
	mu      sync.Mutex
)

func init() {
	flag.Var(&lvl, "log-level", "Adjusts the level of the logs that will be omitted.")
	flag.BoolVar(&logJSON, "log-json", logJSON, "Log in json format.")
}

....

config.Level.SetLevel(lvl)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

zapcore.Level is a int8 though. Doesn't that required --log-level=0 vs --log-level=info?

Copy link
Member

Choose a reason for hiding this comment

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

That's why it's a Var. You'd pass strings. The level implements the flag interface https://github.com/uber-go/zap/blob/master/zapcore/level.go

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TIL there's a flag interface. Cheers 👍

pkg/log/log.go Outdated
cfg = zap.NewProductionConfig()
}

if len(logfilePath) > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

how does rotation work?

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 mistakenly presumed filebeat would handle that for us. I guess I should add support for log rotation via https://github.com/natefinch/lumberjack?

Copy link
Member

Choose a reason for hiding this comment

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

potentially? I was more so just curious how it works. If OKE is handling it with filebeat then that's fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I understand it Filebeat doesn't actually support log rotation though hence my suggestion we do it at the application level.

@@ -106,14 +105,19 @@ func (c *client) GetPrimaryVNICForInstance(ctx context.Context, compartmentID, i

for _, attachment := range resp.Items {
if attachment.LifecycleState != core.VnicAttachmentLifecycleStateAttached {
glog.Infof("VNIC attachment %q for instance %q has a state of %q (not %q)",
*attachment.Id, instanceID, attachment.LifecycleState, core.VnicAttachmentLifecycleStateAttached)
c.logger.With(
Copy link
Member

Choose a reason for hiding this comment

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

You should create a context logger at the beginning of this method call with instance (and maybe compartment id) as fields.

"vnicAttachmentID", *attachment.Id,
"expectedLifecycleState", core.VnicAttachmentLifecycleStateAttached,
"actualLifecycleState", attachment.LifecycleState,
).Info("VNIC attachment in unexpected lifecycle state")
Copy link
Member

Choose a reason for hiding this comment

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

personally i'd just have the log msg as "VNIC attachment is not in attached state" and remove the expected msg.

@@ -96,7 +96,7 @@ func (cp *CloudProvider) NodeAddresses(ctx context.Context, name types.NodeName)
// nodeaddresses are being queried. i.e. local metadata services cannot be used
// in this method to obtain nodeaddresses.
func (cp *CloudProvider) NodeAddressesByProviderID(ctx context.Context, providerID string) ([]api.NodeAddress, error) {
glog.V(4).Infof("NodeAddressesByProviderID(%q) called", providerID)
cp.logger.Debugf("NodeAddressesByProviderID(%q) called", providerID)
Copy link
Member

Choose a reason for hiding this comment

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

These types of log messages are largely useless imo. It'd be more useful to say

cp.logger.With("providerID", providerID).Debug("fetching node addresses by provider id")

@@ -201,9 +202,10 @@ func (cp *CloudProvider) readSSLSecret(svc *v1.Service) (string, string, error)
// balancer, if it doesn't already exist.
func (cp *CloudProvider) ensureSSLCertificate(ctx context.Context, lb *loadbalancer.LoadBalancer, spec *LBSpec) error {
name := spec.SSLConfig.Name
logger := cp.logger.With("certificateName", name, "loadbalancerName", *lb.DisplayName)
Copy link
Member

Choose a reason for hiding this comment

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

I feel we should change this to always use ocid and not display names.

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 believe we always add the ocid as soon as we have it; just including display name as we often have that prior to getting an ocid. Thoughts?

@@ -267,7 +270,7 @@ func (cp *CloudProvider) createLoadBalancer(ctx context.Context, spec *LBSpec) (
Certificates: certs,
}

glog.V(4).Infof("CreateLoadBalancerDetails: %#v", details.String())
logger.With("details", details).Debug("CreateLoadBalancerDetails")
Copy link
Member

Choose a reason for hiding this comment

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

This is gonna be a HUGE log message.... What if the cluster has 500+ nodes? Heck even 20 nodes would be a lot for this haha.

@@ -283,16 +286,16 @@ func (cp *CloudProvider) createLoadBalancer(ctx context.Context, spec *LBSpec) (
return nil, errors.Wrapf(err, "get load balancer %q", *wr.LoadBalancerId)
}

glog.Infof("Created load balancer %q with OCID %q", *lb.DisplayName, *lb.Id)
logger.With("loadbalancerID", *lb.Id).Info("Loadbalancer created")
Copy link
Member

Choose a reason for hiding this comment

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

load balancer

@@ -364,7 +367,7 @@ func (cp *CloudProvider) updateLoadBalancer(ctx context.Context, lb *loadbalance
return errors.Wrap(err, "get subnets for nodes")
}

actions := sortAndCombineActions(backendSetActions, listenerActions)
actions := sortAndCombineActions(cp.logger, backendSetActions, listenerActions)
Copy link
Member

Choose a reason for hiding this comment

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

This and the one above should be context loggers I think w/ at a very minimum the lb id / service name/namespace / something.

@@ -403,7 +406,7 @@ func (cp *CloudProvider) updateBackendSet(ctx context.Context, lbID string, acti
ports = action.Ports
)

glog.V(2).Infof("Applying %q action on backend set %q for lb %q (ports=%+v)", action.Type(), action.Name(), lbID, ports)
cp.logger.Infof("Applying %q action on backend set %q for lb %q (ports=%+v)", action.Type(), action.Name(), lbID, ports)
Copy link
Member

Choose a reason for hiding this comment

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

action stuff should be fields.

Copy link
Member

Choose a reason for hiding this comment

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

lb id should be on the logger already. it gets to be super complex/annoying if we need to add the same fields every where down the call stack.

@jhorwit2
Copy link
Member

jhorwit2 commented Aug 7, 2018

what happens to the existing glog flags around files that never worked?

@prydie
Copy link
Contributor Author

prydie commented Aug 7, 2018

@jhorwit2 Do you think it's worth adding no-op flags for the old glog flags for compat. or given they never worked can we just drop them (with a note in the CHANGELOG)?

pkg/oci/ccm.go Outdated
cp, err := buildConfigurationProvider(config)
logger := logutil.Logger()
defer logger.Sync()
zap.ReplaceGlobals(logger)
Copy link
Member

Choose a reason for hiding this comment

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

Replacing it here means there will be logs emitted not following this logger since the CCM itself logs plus other various global things.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would you suggest swapping out the logger in func main() then?

Copy link
Member

Choose a reason for hiding this comment

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

Yes

@prydie
Copy link
Contributor Author

prydie commented Aug 8, 2018

@jhorwit2 My attempt at moving the logger override func main() resulted in the glog logs going to stderr and rather than respecting logger config and writing to file.

@owainlewis
Copy link
Member

Awaiting a +1 review from @jhorwit2

@jhorwit2
Copy link
Member

@prydie do you know why? that seems odd.

@prydie
Copy link
Contributor Author

prydie commented Aug 13, 2018

@jhorwit2 I was previously creating a new logger in both main.go and ccm.go rather than grabbing a reference.

I'm not overly keen on how I'm getting that reference now but it's working:

2018-08-13T10:16:58.389+0100    INFO    oci-cloud-controller-manager/main.go:59 oci-cloud-controller-manager    {“version”: “0.1.2-94-g91c5b388-dirty”, “build”: “0.1.2-94-g91c5b388-dirty”}
2018-08-13T10:16:58.389+0100    INFO    flag/flags.go:27        FLAG: --address=“0.0.0.0”
2018-08-13T10:16:58.389+0100    INFO    flag/flags.go:27        FLAG: --allocate-node-cidrs=“false”
2018-08-13T10:16:58.389+0100    INFO    flag/flags.go:27        FLAG: --allow-untagged-cloud=“false”

Setting env vars in the form LOG_VAR_field_name=value now adds fields
fields to the logger (e.g. zap.String("field_name", "value") in this
example).
@@ -61,7 +63,15 @@ func Logger() *zap.Logger {
cfg = zap.NewProductionConfig()
}

options := []zap.Option{zap.AddStacktrace(zapcore.FatalLevel)}
// Extract log fields from environment variables.
Copy link
Member

@jhorwit2 jhorwit2 Aug 14, 2018

Choose a reason for hiding this comment

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

What's the need for this? Won't filebeat/fluentd/< insert log shipper > do that for you?

@jhorwit2
Copy link
Member

lgtm

@jhorwit2
Copy link
Member

Actually @prydie could you please update the README for docs on this?

@prydie
Copy link
Contributor Author

prydie commented Aug 15, 2018

@jhorwit2 I'm going to merge and create an issue for a broader effort to improve documentation.

@prydie prydie merged commit 2040fd6 into master Aug 15, 2018
@prydie prydie deleted the ap/zap branch August 15, 2018 12:04
ayushverma14 pushed a commit to ayushverma14/oci-cloud-controller-manager that referenced this pull request Jul 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants