Skip to content

feat: add role fingerprints to syslog [citest_skip]#206

Merged
richm merged 1 commit into
linux-system-roles:mainfrom
richm:fingerprint
Apr 27, 2026
Merged

feat: add role fingerprints to syslog [citest_skip]#206
richm merged 1 commit into
linux-system-roles:mainfrom
richm:fingerprint

Conversation

@richm
Copy link
Copy Markdown
Contributor

@richm richm commented Apr 27, 2026

Feature: Add a fingerprint string to the system log to indicate when the role began
successfully, and when the role finished successfully. The fingerprint string indicates
the role name, a timestamp, and the platform.

Reason: Users can see when the role was used and if it was used successfully. This
information from the system log can be collected by log scanners and aggregators
for further analysis.

Result: The role logs fingerprints to the system log.

This also adds a test to check if the fingerprints were written upon a successful
role invocation.

Signed-off-by: Rich Megginson rmeggins@redhat.com

Summary by Sourcery

Add role-specific syslog fingerprinting for template role runs and verify it via journal-based testing.

New Features:

  • Introduce an sr_fingerprint Ansible module to write structured fingerprint messages to syslog without marking tasks as changed.
  • Record begin and success fingerprint messages for the template system role including role name, Ansible version, and platform details.

Tests:

  • Add an integration test that, when syslog is available, asserts the expected begin and success fingerprint entries are present in the system journal after the role runs.

Chores:

  • Add Ansible sanity ignore files for multiple Ansible versions and link the role library path under tests.

Feature: Add a fingerprint string to the system log to indicate when the role began
successfully, and when the role finished successfully.  The fingerprint string indicates
the role name, a timestamp, and the platform.

Reason: Users can see when the role was used and if it was used successfully.  This
information from the system log can be collected by log scanners and aggregators
for further analysis.

Result: The role logs fingerprints to the system log.

This also adds a test to check if the fingerprints were written upon a successful
role invocation.

Signed-off-by: Rich Megginson <rmeggins@redhat.com>
@richm richm requested a review from spetrosi as a code owner April 27, 2026 18:23
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 27, 2026

Reviewer's Guide

Implements a new sr_fingerprint Ansible module that logs timestamped role begin/success markers to syslog, wires it into the template role at start and completion, and adds a journalctl-based test plus sanity ignore files for the local module library.

Sequence diagram for role fingerprint logging begin/success flow

sequenceDiagram
    actor User
    participant AnsibleController
    participant TemplateRole
    participant SrFingerprintModule
    participant Syslog

    User->>AnsibleController: Invoke template role
    AnsibleController->>TemplateRole: Execute tasks/set_vars.yml
    TemplateRole->>SrFingerprintModule: sr_fingerprint sr_message="begin system_role:template ..."
    SrFingerprintModule->>SrFingerprintModule: _local_iso8601_no_microseconds()
    SrFingerprintModule->>Syslog: module.log("begin system_role:template ... <timestamp>")
    Syslog-->>SrFingerprintModule: Accept log entry
    SrFingerprintModule-->>TemplateRole: exit_json(changed=False)

    AnsibleController->>TemplateRole: Execute remaining role tasks
    TemplateRole->>AnsibleController: Main tasks complete successfully

    AnsibleController->>TemplateRole: Execute tasks/main.yml final task
    TemplateRole->>SrFingerprintModule: sr_fingerprint sr_message="success system_role:template ..."
    SrFingerprintModule->>SrFingerprintModule: _local_iso8601_no_microseconds()
    SrFingerprintModule->>Syslog: module.log("success system_role:template ... <timestamp>")
    Syslog-->>SrFingerprintModule: Accept log entry
    SrFingerprintModule-->>TemplateRole: exit_json(changed=False)
    TemplateRole-->>AnsibleController: Role completed with fingerprints logged
    AnsibleController-->>User: Report role success
Loading

Sequence diagram for sr_fingerprint module behavior including check mode

sequenceDiagram
    participant AnsibleController
    participant SrFingerprintModule
    participant AnsibleModule
    participant Syslog

    AnsibleController->>SrFingerprintModule: Call run_module(sr_message)
    SrFingerprintModule->>AnsibleModule: Create AnsibleModule(argument_spec={sr_message}, supports_check_mode=True)
    SrFingerprintModule->>SrFingerprintModule: _local_iso8601_no_microseconds()
    SrFingerprintModule->>SrFingerprintModule: Build log_message = sr_message + timestamp

    alt check_mode is True
        AnsibleModule-->>AnsibleController: exit_json(changed=False, message="Check mode: message not logged - [log_message]")
    else normal mode
        SrFingerprintModule->>Syslog: AnsibleModule.log(log_message)
        Syslog-->>SrFingerprintModule: Log entry stored
        AnsibleModule-->>AnsibleController: exit_json(changed=False)
    end
Loading

Class diagram for the new sr_fingerprint Ansible module

classDiagram
    class SrFingerprintModule {
        +run_module()
        +main()
        +_local_iso8601_no_microseconds() str
        -log_message str
    }

    class AnsibleModule {
        +params dict
        +check_mode bool
        +log(message str) void
        +exit_json(**kwargs) void
    }

    SrFingerprintModule ..> AnsibleModule : uses

    class SrMessageParameter {
        +sr_message str
    }

    SrFingerprintModule ..> SrMessageParameter : reads

    class TemplateRoleTasks {
        +set_vars_yml
        +main_yml
        +sr_message_begin str
        +sr_message_success str
    }

    TemplateRoleTasks ..> SrFingerprintModule : invokes

    class SetVarsTask_RecordBeginFingerprint {
        +name Record_role_begin_fingerprint
        +module sr_fingerprint
        +sr_message str
    }

    class MainTask_RecordSuccessFingerprint {
        +name Record_role_success_fingerprint
        +module sr_fingerprint
        +sr_message str
    }

    TemplateRoleTasks *-- SetVarsTask_RecordBeginFingerprint
    TemplateRoleTasks *-- MainTask_RecordSuccessFingerprint
Loading

File-Level Changes

Change Details Files
Introduce sr_fingerprint custom Ansible module to write fingerprint messages to syslog with a standardized local ISO-8601 timestamp and no state change.
  • Add library/sr_fingerprint.py implementing a module that accepts a required sr_message parameter and logs it via module.log() with an appended local ISO-8601 timestamp (no microseconds).
  • Implement _local_iso8601_no_microseconds() helper with compatibility path for older Python lacking datetime.timezone, preferring local timezone and falling back to UTC-based conversion.
  • Ensure module supports check_mode, reporting no change and skipping logging in check mode, and always exits with changed=False in normal runs.
library/sr_fingerprint.py
Wire role begin/success fingerprints into the template role execution flow using the sr_fingerprint module.
  • Add a "Record role begin fingerprint" task early in tasks/set_vars.yml that logs a "begin system_role:template" fingerprint including ansible version and distribution/version facts.
  • Add a "Record role success fingerprint" task at the end of tasks/main.yml that logs a "success system_role:template" fingerprint including ansible version and distribution/version facts.
  • Ensure fingerprints are purely logging side-effects and do not alter Ansible change status, preserving idempotency semantics.
tasks/set_vars.yml
tasks/main.yml
Extend default role test to verify fingerprints are written to the system journal when syslog is available.
  • Add a stat task on /dev/log and gate fingerprint checks on its existence to avoid failures on systems without a local syslog socket.
  • Capture a __journal_start_time fact from ansible_facts.date_time immediately before running the role to bound journalctl queries to the current test run.
  • Add a shell-based test that uses journalctl since __journal_start_time, filters out noisy "Invoked with" messages, and greps for both begin and success fingerprint patterns, failing with clear error messages if either is missing; mark the task changed_when: false.
tests/tests_default.yml
Adjust Ansible sanity configuration to allow the custom module library used by tests.
  • Add versioned .sanity-ansible-ignore-2.xx.txt files to bypass relevant sanity checks for this collection's layout and local module usage.
  • Add tests/roles/linux-system-roles.template/library path (likely a symlink or directory marker) so tests can import the sr_fingerprint module from the role context.
.sanity-ansible-ignore-2.14.txt
.sanity-ansible-ignore-2.16.txt
.sanity-ansible-ignore-2.17.txt
.sanity-ansible-ignore-2.18.txt
.sanity-ansible-ignore-2.19.txt
.sanity-ansible-ignore-2.20.txt
.sanity-ansible-ignore-2.21.txt
.sanity-ansible-ignore-2.22.txt
tests/roles/linux-system-roles.template/library

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@richm richm merged commit 811990f into linux-system-roles:main Apr 27, 2026
11 checks passed
@richm richm deleted the fingerprint branch April 27, 2026 18:24
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The fingerprint message format is duplicated in both the "begin" and "success" tasks; consider constructing the common prefix (role name, ansible_version, platform) once via a variable or template to keep the format consistent and easier to change later.
  • The journalctl test greps for "sr_fingerprint.*begin system_role:template", but the module only logs the sr_message plus a timestamp; aligning the grep pattern with the actual log format (and avoiding unnecessary hard-coding of the module name/role name where possible) will make the test more robust and less brittle to internal logging prefix changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The fingerprint message format is duplicated in both the "begin" and "success" tasks; consider constructing the common prefix (role name, ansible_version, platform) once via a variable or template to keep the format consistent and easier to change later.
- The journalctl test greps for "sr_fingerprint.*begin system_role:template", but the module only logs the sr_message plus a timestamp; aligning the grep pattern with the actual log format (and avoiding unnecessary hard-coding of the module name/role name where possible) will make the test more robust and less brittle to internal logging prefix changes.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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.

1 participant