') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - htfy96/logalign: Command-line tool to annotate log lines with links to their definitons and argument expression. · GitHub
Skip to content

Repository files navigation

logalign

LogAlign is a command-line tool to annotate log lines with links to their definitons and argument expression.

screenshot

Usage

Download the latest linux-amd64 canary build from Release.

Dependency

This tool depends on libpcre2 and libhyperscan5 to run. Install them from your system's package manager.

Command-line Usage

First, users need to build a corpus from source files to extract all relevant log calls. This guide uses openssh as an example.

Clone and download the source of openssh. run logalign corpus new-config to generate a sample configuration. Edit .logalign.toml to the follows:

project = 'openssh'# source files to grepsource_regex = '.*\.c'ignore_source_regex = 'generated\.c$'# Could define multiple [[definitions]] under different 'id'
[[definitions]]
id = 'openssh_logs'# This is a Treesitter query# See https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries for the full syntax# Use https://intmainreturn0.com/ts-visualizer/ to visualize the TreeSitter AST for a given code snippet## It needs to capture three components:# - @method: the log function name# - @format_string: a printf-like format string. Should not include surrounding quotes# - @argument_expr. Each @argument_expr should match one argument passed to the log call. Must match the number of# directives in format_stringquery = """(call_expression function: (identifier) @method (#match? @method \"(logit|error|debug|fatal|logdie|verbose|debug3|debug2)(_f|_r|_fr)?\") arguments: (argument_list\"(\" [(concatenated_string (string_literal _* [(string_content) (escape_sequence) ]+ @format_string _* )+ ) (string_literal _* [(string_content) (escape_sequence) ]+ @format_string _* ) ] (\",\" (_) @argument_expr )*\")\" ))"""# language to run this query. Currently supports c,cpp,java,golang,javascript,python,typescriptlanguage = 'c'syntax = 'printflike'# A template string to link to the source at {file} {line}link_template = 'https://github.com/openssh/openssh-portable/blob/master/{file}#L{line}'# Remove redundant '\n' at the end of @format_stringstrip_tailing_newline = true

Then, run logalign corpus build. It should output Corpus built successfully.

Check the generated corpus via logalign corpus ls and logalign corpus cat openssh.

To annoate log files based on built corpus, run logalign corpus view /var/log/auth.log. If your terminal supports OSC-8, you can control/meta/alt click the left source panel to jump to the definitions.

LICENSE

Apache v2

About

Command-line tool to annotate log lines with links to their definitons and argument expression.

Topics

Resources

Stars

5 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages