Skip to content

LogViewer

<caos-log-viewer>

one log read as structured lines, filtered by category or by text

May be placed on a page inside an app.

Name Attribute Description Type Default Required
lines property only The log as structured lines: { number, at?, event?, detail?, category? }[]. number is the position in the ORIGINAL log and is never renumbered by filtering. json empty list Optional
raw property only The log as raw text, for a log that could not be parsed. Shown ONLY when there are no lines, together with a line saying it is unstructured — so unparseable and empty never look alike. text none declared Optional
category category, markup only Show only lines of this category. A FILTER, not a text search for the category name — searching for “debug” also matches every line whose detail contains the word, and misses debug lines that do not say so. The dropdown offers only the categories present in this log. text — recognises executable, debug, system, error; anything else reads as every category, when the attribute is absent or empty none declared Optional
search search, markup only Narrows by text across the timestamp, event and detail. Intersects with the category filter rather than replacing it — “the debug lines mentioning this record id” is the actual question. text none declared Optional
emptyText empty-text, markup only What to say for a log with no lines in it at all. text This log is empty. Optional
Name When it fires What it carries
caos-log-filter The category filter changes. { category, search }.

Not documented yet — this piece has not said.

Not documented yet — this piece has not said.

Not documented yet — this piece has not said.

Name Type What it tells you
visibleLines CaosLogLine[] The lines surviving both filters.
categories CaosLogCategory[] The categories present in this log — what the filter offers.
Part Which piece of it When it is there
::part(viewer) The outer column. Always
::part(toolbar) The filter and search row. Always
::part(filter) The category dropdown. Always
::part(search) The search box. Always
::part(summary) The line count and error count. Always
::part(lines) The scrolling list of lines. Always
::part(line) One line. Always
::part(at) A line’s timestamp. Always
::part(event) A line’s event name. Always
::part(detail) The rest of a line. Always
::part(raw) The unparsed text. The log arrived as raw text with no lines.

When one log has been chosen and the question is what happened in it.

  • LogList — somebody is choosing WHICH log to read.
  • FieldRenderer — the text is a record’s rich-text field being displayed rather than machine output being searched.

The summary is a role="status" live region stating how many of the whole log survived the filters — a filtered log that does not say it is filtered is how somebody concludes a run logged four lines. The error count is stated there in words rather than being left to the red on the rows. Both controls carry their own accessible names. The original line numbers are kept, so a line read here can be found in the raw text a colleague is looking at.

Three columns and the original line numbers. The error count is stated in the summary, not left to somebody spotting the red.

{
"id": "example",
"section": "A log read as lines",
"columns": 1,
"items": [
{
"id": "log_viewer_1",
"type": "component",
"key": "log_viewer",
"inputs": {
"lines": [
{
"number": 1,
"at": "15:58:01.004",
"event": "EXECUTION_STARTED",
"category": "system"
},
{
"number": 2,
"at": "15:58:01.006",
"event": "CODE_UNIT_STARTED",
"detail": "AccountTrigger on Account",
"category": "executable"
},
{
"number": 3,
"at": "15:58:01.021",
"event": "USER_DEBUG",
"detail": "resolving 412 line items",
"category": "debug"
},
{
"number": 4,
"at": "15:58:01.244",
"event": "SOQL_EXECUTE_BEGIN",
"detail": "select id from account where id = :ids",
"category": "executable"
},
{
"number": 5,
"at": "15:58:02.118",
"event": "FATAL_ERROR",
"detail": "System.NullPointerException line 48",
"category": "error"
},
{
"number": 6,
"at": "15:58:02.119",
"event": "EXECUTION_FINISHED",
"category": "system"
}
]
}
}
]
}
<caos-log-viewer id="logViewer1"></caos-log-viewer>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const logViewer1 = document.getElementById('logViewer1');
logViewer1.lines = [
{
"number": 1,
"at": "15:58:01.004",
"event": "EXECUTION_STARTED",
"category": "system"
},
{
"number": 2,
"at": "15:58:01.006",
"event": "CODE_UNIT_STARTED",
"detail": "AccountTrigger on Account",
"category": "executable"
},
{
"number": 3,
"at": "15:58:01.021",
"event": "USER_DEBUG",
"detail": "resolving 412 line items",
"category": "debug"
},
{
"number": 4,
"at": "15:58:01.244",
"event": "SOQL_EXECUTE_BEGIN",
"detail": "select id from account where id = :ids",
"category": "executable"
},
{
"number": 5,
"at": "15:58:02.118",
"event": "FATAL_ERROR",
"detail": "System.NullPointerException line 48",
"category": "error"
},
{
"number": 6,
"at": "15:58:02.119",
"event": "EXECUTION_FINISHED",
"category": "system"
}
];

The numbers stay as they were. A filtered log renumbered 1..40 destroys the only thing connecting a line back to the raw text.

{
"id": "example",
"section": "Filtered to the debug lines",
"columns": 1,
"items": [
{
"id": "log_viewer_1",
"type": "component",
"key": "log_viewer",
"inputs": {
"category": "debug",
"lines": [
{
"number": 1,
"at": "15:58:01.004",
"event": "EXECUTION_STARTED",
"category": "system"
},
{
"number": 3,
"at": "15:58:01.021",
"event": "USER_DEBUG",
"detail": "resolving 412 line items",
"category": "debug"
},
{
"number": 9,
"at": "15:58:01.880",
"event": "USER_DEBUG",
"detail": "tax band B applied",
"category": "debug"
},
{
"number": 11,
"at": "15:58:02.118",
"event": "FATAL_ERROR",
"detail": "System.NullPointerException",
"category": "error"
}
]
}
}
]
}
<caos-log-viewer id="logViewer1" category="debug"></caos-log-viewer>
// What an attribute cannot hold, set as a property — the same values the preview is drawn with.
const logViewer1 = document.getElementById('logViewer1');
logViewer1.lines = [
{
"number": 1,
"at": "15:58:01.004",
"event": "EXECUTION_STARTED",
"category": "system"
},
{
"number": 3,
"at": "15:58:01.021",
"event": "USER_DEBUG",
"detail": "resolving 412 line items",
"category": "debug"
},
{
"number": 9,
"at": "15:58:01.880",
"event": "USER_DEBUG",
"detail": "tax band B applied",
"category": "debug"
},
{
"number": 11,
"at": "15:58:02.118",
"event": "FATAL_ERROR",
"detail": "System.NullPointerException",
"category": "error"
}
];

The text is shown as it arrived, with a line saying so — so “could not be parsed” and “nothing happened” never look the same.

{
"id": "example",
"section": "A log that could not be read as lines",
"columns": 1,
"items": [
{
"id": "log_viewer_1",
"type": "component",
"key": "log_viewer",
"inputs": {
"raw": "62.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO\nExecute Anonymous: System.debug(1);\n15:58:01.4 (4123456)|USER_DEBUG|[1]|DEBUG|1"
}
}
]
}
<caos-log-viewer raw="62.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO
Execute Anonymous: System.debug(1);
15:58:01.4 (4123456)|USER_DEBUG|[1]|DEBUG|1"></caos-log-viewer>