Skip to content

Utility functions and scripts for Debug Framework #618

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,25 @@ def naming_mode_alias():
"""Set CLI interface naming mode to ALIAS (Vendor port alias)"""
set_interface_naming_mode('alias')

#
# 'assert' group ('config assert ...')
#
@config.group()
def custom_assert():
"""Configuration action on assert"""
pass

@custom_assert.command()
@click.argument('action', metavar='<action>', default='ABORT', required=False,
type=click.Choice(['SYSLOG', 'BTRACE', 'DUMP', 'ABORT']))
def action(action):
""" Configure the action to execute when assert condition is false"""
config_db = ConfigDBConnector()
config_db.connect()
table = "DEBUGFM_CONFIG_TABLE"
key = "ASSERTACT"
config_db.set_entry(table, key, {"ASSERTACT": action})

#
# 'syslog' group ('config syslog ...')
#
Expand Down
136 changes: 136 additions & 0 deletions scripts/dumpinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/usr/bin/python
from swsscommon import swsscommon
import argparse
"""
using debugdump to display internal debug information of SONiC components

usage: debugdump [-h] [-u] [-c] [-s] [-l] [-o]

Dump Debug Information of SONiC components

optional arguments:
-h, --help show this help message and exit
-u, --action post action upload default is compress
-c, --component dump info for specified component
-s, --detail short summary default is full
-l, --location target location syslog
-o, --optargs optional additional arguments to components

"""

class DebugDump(object):

def __init__(self):
self.target = "file"
self.component = "all"
self.detail = "full"
self.post_action = "compress"
self.argList = ""

def set_dump_target(self, location):
"""
Set the target location for the dump syslog|file file is /var/log/<compName>_dump.log
:param location: target
:return:
"""
self.target = location

def set_dump_component(self, component_name):
"""
Set the component_name which need to dump the debug info
:param component_name: component
:return:
"""
self.component = component_name

def set_detail_level(self, level):
"""
Set the level of detail to dump short or full
:param level: detail
:return:
"""
self.detail = level

def set_post_action(self, action):
"""
Set the action after collecting the dump
:param action: post_action
:return:
"""
self.post_action = action

def add_args_for_component(self, field, value):
"""
append to the list of the arguments for the component interpretation
:param field: argType
:param value: argVal
:return:
"""
if len(self.argList):
self.argList += ";"

self.argList += "{}:{}".format(field, value)

def invoke_dump_trigger(self, componentName, optargList):
"""
invoke the trigger to framework and components to collect debug info
"""
args = "";
if (self.target == "file"):
args += "TARGET:SWSS_FILE"
else:
args += "TARGET:SWSS_SYSLOG"

if (self.detail == "full"):
args += ";DETAIL:FULL"
else:
args += ";DETAIL:SHORT"

if (self.post_action == "compress"):
args += ";ACTION:COMPRESS;"
else:
args += ";ACTION:UPLOAD;"

args += self.argList
args += optargList

if (self.component == "all"):
swsscommon.Debugframework_invokeTrigger("all", args)
else:
swsscommon.Debugframework_invokeTrigger(self.component, args)

return

def main():
parser = argparse.ArgumentParser(description='Dump internal debug information of SONiC components',
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-u', '--upload', action='store_true', help='specify action as upload')
parser.add_argument('-c', '--component', type=str, help='specified component')
parser.add_argument('-s', '--detail', action='store_true', help='dump only short detail')
parser.add_argument('-l', '--location', action='store_true', help='dump to syslog')
parser.add_argument('-o', '--optargs', type=str, help='comma seperated args')
args = parser.parse_args()

try:
dump = DebugDump()
if args.upload:
dump.set_post_action("upload")
if args.component:
dump.set_dump_component(args.component)
if args.detail:
dump.set_detail_level("short")
if args.location:
dump.set_dump_target("syslog")

if args.optargs:
dump.invoke_dump_trigger(dump.component, args.optargs)
else:
dump.invoke_dump_trigger(dump.component, "")

except Exception as e:
print(e.message)
sys.exit(1)

if __name__ == "__main__":
main()

17 changes: 17 additions & 0 deletions scripts/generate_debugdump
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
#
# Generate debugging information
#

set -u

#Copy the python dumpinfo script to swss container
sudo docker cp /usr/bin/dumpinfo swss:/usr/bin/dumpinfo

#execute the dumpinfo python script in docker
sudo docker exec -i swss python /usr/bin/dumpinfo $@

#Copy the log files to host system /var/log/
#sudo docker exec -i swss touch /var/log/fdborch_debug.log
#sudo docker cp swss:/var/log/fdborch_debug.log /var/log/fdborch_debug.log

4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@
'scripts/teamshow',
'scripts/warm-reboot',
'scripts/watermarkstat',
'scripts/watermarkcfg'
'scripts/watermarkcfg',
'scripts/generate_debugdump',
'scripts/dumpinfo'
],
data_files=[
('/etc/bash_completion.d', glob.glob('data/etc/bash_completion.d/*')),
Expand Down
58 changes: 58 additions & 0 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,64 @@ def techsupport(since, verbose):
cmd += " -s {}".format(since)
run_command(cmd, display_cmd=verbose)

#
# 'debug' group ("show debug")
#

@cli.group(cls=AliasedGroup, default_if_no_args=False)
def debug():
"""Collect debugging information from components"""
pass

# 'all' subcommand ("show debug all")
@debug.command()
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def all(verbose):
"""Collect debugging information from all components"""
cmd = "sudo generate_debugdump"
run_command(cmd, display_cmd=verbose)

# 'component' subcommand ("show debug component <component name>")
@debug.command()
@click.argument('componentname', required=True)
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def component(componentname, verbose):
"""Collect debugging information from component"""
cmd = "sudo generate_debugdump -c "

if componentname is not None:
cmd += format(componentname)

run_command(cmd, display_cmd=verbose)

#
# 'tosyslog' group ###
#
@debug.group(cls=AliasedGroup, default_if_no_args=False)
def tosyslog():
"""Write the logs to syslog"""
pass

# 'all' subcommand ("show debug tosyslog all")
@tosyslog.command()
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def all(verbose):
"""Collect debugging information from all components and write in syslog"""
cmd = "sudo generate_debugdump -l "
run_command(cmd, display_cmd=verbose)

# 'component' subcommand ("show debug tosyslog component <component name>")
@tosyslog.command()
@click.argument('componentname', required=True)
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def component(componentname, verbose):
"""Collect debugging information from component and write in syslog"""
cmd = "sudo generate_debugdump -l -c "

if componentname is not None:
cmd += format(componentname)

run_command(cmd, display_cmd=verbose)

#
# 'runningconfiguration' group ("show runningconfiguration")
Expand Down