diff --git a/configuration/contrib/log-plugins/dmesg b/configuration/contrib/log-plugins/dmesg new file mode 100755 index 00000000000..0cf9dd1213c --- /dev/null +++ b/configuration/contrib/log-plugins/dmesg @@ -0,0 +1,138 @@ +#!/bin/sh +set -eu + +NOT_SUPPORTED=2 + +usage() { + cat < [options] + Fetch logs for the given facility () + +Options for "get": + --since Show logs since the given timestamp (seconds since epoch) + --until Show logs up to the given timestamp (seconds since epoch) + --help Show this help message and exit + +Examples: + $0 list + $0 get all --since 1696250000 --until 1696260000 +EOT +} + +is_busy_box() { + if dmesg --help 2>&1 | grep -q "facility"; then + return 1 + fi + return 0 +} + +list_log_types() { + if ! command -V dmesg >/dev/null 2>&1; then + exit "$NOT_SUPPORTED" + fi + + # Note: The dmesg implementations vary a lot on different + # operating systems, so facility filtering is difficult to provide + printf 'all\n' # Default type +} + +format_timestamp() { + value="$1" + case "$value" in + ''|*[!0-9]*) + echo "$value" + ;; + *) + # convert unix timestamp to iso date, as dmesg does not support unix timestamps + date -d @"$value" +%Y-%m-%d\ %H:%M:%S + ;; + esac +} + +get_logs() { + # Note: the log type is unused, but still enforce the cli contract + if [ $# -lt 1 ]; then + echo "Error: 'get' command expects a mandatory arguments" >&2 + usage + exit 1 + fi + _log_type="$1" + shift + + # default to a large time period as kernel messages aren't published so frequently + since="90 day ago" + until="0 second ago" + + while [ $# -gt 0 ]; do + case $1 in + --since) + since=$(format_timestamp "$2") + shift + ;; + + --until) + until=$(format_timestamp "$2") + shift + ;; + + --help) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac + shift + done + + # try calling with all filters, and fallback to a plain dmesg command + if ! dmesg \ + --nopager \ + --time-format=iso \ + --color=never \ + --since "$since" \ + --until "$until" 2>/dev/null; then + + echo "WARNING: dmesg version does not advanced flags, so calling using 'dmesg' instead" >&2 + dmesg + fi +} + +main() { + if [ $# -lt 1 ]; then + usage + exit 1 + fi + + SUBCOMMAND="$1" + shift + + case "$SUBCOMMAND" in + "list") + list_log_types + ;; + "get") + get_logs "$@" + ;; + *) + echo "Error: Unknown subcommand '$SUBCOMMAND'" >&2 + usage + exit 1 + ;; + esac +} + +main "$@" diff --git a/configuration/package_manifests/nfpm.tedge.yaml b/configuration/package_manifests/nfpm.tedge.yaml index 9d32b2c5f54..862d9a8b04b 100644 --- a/configuration/package_manifests/nfpm.tedge.yaml +++ b/configuration/package_manifests/nfpm.tedge.yaml @@ -114,6 +114,12 @@ contents: mode: 0755 packager: rpm + # dmesg + - src: ./configuration/contrib/log-plugins/dmesg + dst: /usr/share/tedge/log-plugins/ + file_info: + mode: 0755 + # preset diagnostic plugins - src: ./configuration/contrib/diag-plugins/01_tedge.sh dst: /usr/share/tedge/diag-plugins/ diff --git a/tests/RobotFramework/tests/cumulocity/log/log_operation_plugins_dmesg.robot b/tests/RobotFramework/tests/cumulocity/log/log_operation_plugins_dmesg.robot new file mode 100644 index 00000000000..5709fd9d22c --- /dev/null +++ b/tests/RobotFramework/tests/cumulocity/log/log_operation_plugins_dmesg.robot @@ -0,0 +1,45 @@ +*** Settings *** +Resource ../../../resources/common.resource +Library DateTime +Library OperatingSystem +Library String +Library Cumulocity +Library ThinEdgeIO + +Suite Setup Custom Setup +Test Teardown Get Logs + +Test Tags theme:c8y theme:log + + +*** Test Cases *** +Log operation dmesg plugin + Should Contain Supported Log Types all::dmesg + ${start_timestamp}= Get Current Date UTC -1 hours result_format=%Y-%m-%dT%H:%M:%S+0000 + ${end_timestamp}= Get Current Date UTC +1 hours result_format=%Y-%m-%dT%H:%M:%S+0000 + ${operation}= Cumulocity.Get Log File + ... type=all::dmesg + ... date_from=${start_timestamp} + ... date_to=${end_timestamp} + ... maximum_lines=100 + ${operation}= Operation Should Be SUCCESSFUL ${operation} + Log Operation Attachment File Should Not Be Empty + ... ${operation} + + +*** Keywords *** +Custom Setup + ${DEVICE_SN}= Setup + Set Suite Variable $DEVICE_SN + Device Should Exist ${DEVICE_SN} + ThinEdgeIO.Service Health Status Should Be Up tedge-agent + +Log Operation Attachment File Should Not Be Empty + [Arguments] ${operation} + ${event_url_parts}= Split String ${operation["c8y_LogfileRequest"]["file"]} separator=/ + ${event_id}= Set Variable ${event_url_parts}[-2] + ${contents}= Cumulocity.Event Should Have An Attachment + ... ${event_id} + ... encoding=utf-8 + ... expected_size_min=1 + RETURN ${contents}