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

[generic_config_updater] Logging #1864

Merged
merged 3 commits into from
Oct 14, 2021

Conversation

ghooo
Copy link
Contributor

@ghooo ghooo commented Oct 7, 2021

What I did

Add some logs to generic_updater

How I did it

How to verify it

Previous command output (if the output of a command-line utility has changed)

New command output (if the output of a command-line utility has changed)

Empty patch

admin@vlab-01:~$ sudo config apply-patch empty.json-patch 
Patch Applier: Patch application starting.
Patch Applier: Patch: []
Patch Applier: Validating patch is not making changes to tables without YANG models.
Patch Applier: Getting current config db.
Patch Applier: Simulating the target full config after applying the patch.
Patch Applier: Validating target config according to YANG models.
... [logs from sonic-yang-mgmt framework]
Patch Applier: Sorting patch updates.
Patch Applier: The patch was sorted into 0 changes.
Patch Applier: Applying changes in order.
Patch Applier: Verifying patch updates are reflected on ConfigDB.
Patch Applier: Patch application completed.
Patch applied successfully.
admin@vlab-01:~$ 

Single change patch

admin@vlab-01:~$ sudo config apply-patch dhcp_add.json-patch 
Patch Applier: Patch application starting.
Patch Applier: Patch: [{"op": "add", "path": "/VLAN/Vlan1000/dhcp_servers/4", "value": "192.0.0.5"}]
Patch Applier: Validating patch is not making changes to tables without YANG models.
Patch Applier: Getting current config db.
Patch Applier: Simulating the target full config after applying the patch.
Patch Applier: Validating target config according to YANG models.
... [logs from sonic-yang-mgmt framework]
Patch Applier: The patch was sorted into 1 change:
Patch Applier:   * [{"op": "add", "path": "/VLAN/Vlan1000/dhcp_servers/4", "value": "192.0.0.5"}]
Patch Applier: Applying changes in order.
Failed to apply patch
Usage: config apply-patch [OPTIONS] PATCH_FILE_PATH
Try "config apply-patch -h" for help.

Error: ChangeApplier.apply(change) is not implemented yet
admin@vlab-01:~$ 

Multi change patch:

admin@vlab-01:~$ sudo config apply-patch update_lanes.json-patch 
Patch Applier: Patch application starting.
Patch Applier: Patch: [{"op": "replace", "path": "/PORT/Ethernet100/lanes", "value": "121,122,123"}]
Patch Applier: Validating patch is not making changes to tables without YANG models.
Patch Applier: Getting current config db.
Patch Applier: Simulating the target full config after applying the patch.
Patch Applier: Validating target config according to YANG models.
... [logs from sonic-yang-mgmt framework]
Patch Applier: Sorting patch updates.
... [logs from sonic-yang-mgmt framework]
Patch Applier: The patch was sorted into 2 changes:
Patch Applier:   * [{"op": "remove", "path": "/PORT/Ethernet100"}]
Patch Applier:   * [{"op": "add", "path": "/PORT/Ethernet100", "value": {"alias": "fortyGigE0/100", "description": "fortyGigE0/100", "index": "25", "lanes": "121,122,123", "mtu": "9100", "pfc_asym": "off", "speed": "40000", "tpid": "0x8100"}}]
Patch Applier: Applying changes in order.
Failed to apply patch
Usage: config apply-patch [OPTIONS] PATCH_FILE_PATH
Try "config apply-patch -h" for help.

Error: ChangeApplier.apply(change) is not implemented yet
admin@vlab-01:~$ 

@lgtm-com
Copy link

lgtm-com bot commented Oct 7, 2021

This pull request introduces 5 alerts when merging b56fbde0b7b5bac8e7056ceb1ee80260c823bd3d into d13955a - view on LGTM.com

new alerts:

  • 4 for Wrong number of arguments in a call
  • 1 for First parameter of a method is not named 'self'

@ghooo ghooo force-pushed the dev/mghoneim/gu/syslogging branch from b56fbde to 82b53eb Compare October 11, 2021 17:58
@ghooo ghooo changed the title [generic_config_updater] Syslogging [generic_config_updater] Logging Oct 11, 2021
@ghooo ghooo force-pushed the dev/mghoneim/gu/syslogging branch from 82b53eb to a35081b Compare October 11, 2021 18:03
import subprocess
import yang as ly
import copy
import re
from enum import Enum

YANG_DIR = "/usr/local/yang-models"
SYSLOG_IDENTIFIER = "GenericConfigUpdater"
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 12, 2021

Choose a reason for hiding this comment

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

GenericConfigUpdater

Is this ident too long? The default will be process name such as config, is it good enough since you have add title to diffentiate. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is how it look like:

Oct 11 18:15:50.604939 vlab-01 INFO GenericConfigUpdater: Patch Applier: Getting current config db.
Oct 11 18:15:51.494117 vlab-01 INFO GenericConfigUpdater: Patch Applier: Simulating the target full config after applying the patch.
Oct 11 18:15:51.502449 vlab-01 INFO GenericConfigUpdater: Patch Applier: Validating target config according to YANG models.

I think it is OK, this way I can grep all syslogs associated with GenericConfigUpdater i.e. cat /var/log/syslog | grep GenericConfigUpdater

I think we will add more logs to other parts such config replace, rollback checkpoint and the applier.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also I don't think we should use config since this library might be used with REST APIs like was requested in some of the earlier meetings with SONiC Community

self.config_wrapper = config_wrapper if config_wrapper is not None else ConfigWrapper()
self.patch_wrapper = patch_wrapper if patch_wrapper is not None else PatchWrapper()
self.patchsorter = patchsorter if patchsorter is not None else PatchSorter(self.config_wrapper, self.patch_wrapper)
self.changeapplier = changeapplier if changeapplier is not None else ChangeApplier()

def apply(self, patch):
logger.log_info(self.LOGTITLE, "Patch application starting.")
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 12, 2021

Choose a reason for hiding this comment

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

self.LOGTITLE

You add the same title everywhere. Is it better to define an instance in this class, and init with the title. #Closed

Copy link
Contributor Author

@ghooo ghooo Oct 12, 2021

Choose a reason for hiding this comment

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

This way makes it easier to add new log msgs, I don't have to create a new instance of logger for each class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nvm, created a logger instance for the PatchApplier class

@@ -691,3 +693,44 @@ def _get_model(self, model, name):
return submodel

return None

class GenericUpdaterLogger:
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 12, 2021

Choose a reason for hiding this comment

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

GenericUpdaterLogger

This class seems have general value, like https://github.com/Azure/sonic-buildimage/blob/master/src/sonic-py-common/sonic_py_common/logger.py.

Is it better to enhance existing Logger class? If something is impossible, we can inherit the class. #Closed

Copy link
Contributor Author

@ghooo ghooo Oct 13, 2021

Choose a reason for hiding this comment

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

used sonic-py-common logger

Console settings: log levels [error, warning, info] always printed, [debug] only printed if verbose logging
Syslog settings: log all levels [error, warning, info, debug]
"""
def init_verbose_logging(self, verbose):
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 12, 2021

Choose a reason for hiding this comment

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

init_verbose_logging

Better use __init__() #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if I use __init__ it means when creating the logger I initialize verbose, but this is not the case as we modify verbosity later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used loggingSettings instead and the logger is created from loggingSettings.getlogger

def _log_to_console(self, msg, logLevel):
# Always log [warning, error, info] i.e. not debug, but if verbose logging print debug as well
if logLevel < syslog.LOG_DEBUG or self.enable_verbose_logging:
print(msg)
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 12, 2021

Choose a reason for hiding this comment

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

print

It is an error, should we print to stderr? How about warning? #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used common logger logic

syslog.syslog(logLevel, msg)
syslog.closelog()

logger = GenericUpdaterLogger()
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 12, 2021

Choose a reason for hiding this comment

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

logger

If global object is used by multiple places, and init verbose multiple time, user will be confused about the interference #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea is to have a single global logger in gu_common for which verbosity can be modified.

Another idea is to create an init_env(...) method in gu_common and this function takes care of creating the logger.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

global loggingSettings and then each logger instance is created per class, there is no global logger

Copy link
Contributor

Choose a reason for hiding this comment

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

init_env(...) will solve the user confusing issue I mentioned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@qiluo-msft I have used loggingSettings instead, there the verbose flag can change, but then once a logger is created its verbosity can not change. Do you think this is confusing?

@ghooo ghooo force-pushed the dev/mghoneim/gu/syslogging branch from 10fd12d to 0789414 Compare October 13, 2021 00:39
@ghooo ghooo force-pushed the dev/mghoneim/gu/syslogging branch from 0789414 to ad29105 Compare October 13, 2021 00:40
def getLogger(self, title):
return GenericUpdaterLogger(title, self._verbose)

loggingSettings = LoggingSettings()
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 14, 2021

Choose a reason for hiding this comment

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

loggingSettings

rename: logger #Closed

@@ -691,3 +693,26 @@ def _get_model(self, model, name):
return submodel

return None

class GenericUpdaterLogger(logger.Logger):
def __init__(self, title, verbose):
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 14, 2021

Choose a reason for hiding this comment

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

title

Also add ident as another parameter #Closed

@@ -691,3 +693,26 @@ def _get_model(self, model, name):
return submodel

return None

class GenericUpdaterLogger(logger.Logger):
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 14, 2021

Choose a reason for hiding this comment

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

GenericUpdaterLogger

rename: TitledLogger.
It could be design more general. #Closed

combined_msg = f"{self._title}: {msg}"
super().log(priority, combined_msg, also_print_to_console)

class LoggingSettings:
Copy link
Contributor

@qiluo-msft qiluo-msft Oct 14, 2021

Choose a reason for hiding this comment

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

LoggingSettings

rename: GenericUpdaterLogger #Closed

@ghooo ghooo force-pushed the dev/mghoneim/gu/syslogging branch from ab35ee6 to 4539f6b Compare October 14, 2021 01:14
@ghooo ghooo merged commit 4d732c6 into sonic-net:master Oct 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants