Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Render structured logs in the new UI rather than showing raw JSON by ashb · Pull Request #46827 · apache/airflow · GitHub
Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Render structured logs in the new UI rather than showing raw JSON by ashb · Pull Request #46827 · apache/airflow · GitHub
Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', '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('^' + ".*" + ' Render structured logs in the new UI rather than showing raw JSON by ashb · Pull Request #46827 · apache/airflow · GitHub
Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv
, '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" + ' Render structured logs in the new UI rather than showing raw JSON by ashb · Pull Request #46827 · apache/airflow · GitHub
Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv
, '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('^' + ".*" + ' Render structured logs in the new UI rather than showing raw JSON by ashb · Pull Request #46827 · apache/airflow · GitHub
Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv
, '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); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Render structured logs in the new UI rather than showing raw JSON by ashb · Pull Request #46827 · apache/airflow · GitHub
Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Render structured logs in the new UI rather than showing raw JSON by ashb · Pull Request #46827 · apache/airflow · GitHub
Skip to content

Render structured logs in the new UI rather than showing raw JSON - #46827

Merged
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui
Feb 27, 2025
Merged

Render structured logs in the new UI rather than showing raw JSON#46827
Lee-W merged 19 commits into
mainfrom
render-json-logs-new-ui

Conversation

@ashb

@ashbashb commented Feb 17, 2025

Copy link
Copy Markdown
Member

Closes#46657

There are multiple parts to this PR

First off: the log reader interface was a mess There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.

This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.

I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.

The current rendered HTML looks like this:

<p><spanclass="event">::group::Log message source details</span><spanclass="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p><p><spanclass="event">::endgroup::</span></p><p>[<timedatetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <spanclass="log-level debug">DEBUG</span> - <spanclass="event">Hook impls: []</span><spanclass="log-key logger">logger="airflow.listeners.listener"</span></p>

Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson

It's not the prettiest yet, I'll leave that to people more talented at that than me

Screenshot 2025-02-17 at 14 58 44

^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@boring-cyborgboring-cyborgBot added area:logging area:UI Related to UI/UX. For Frontend Developers. labels Feb 17, 2025
@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

@ashb

ashb commented Feb 17, 2025

Copy link
Copy Markdown
MemberAuthor

I have not tested this with an old/non-json Log, and I haven't fixed up the unit tests yet either.

@bbovenzi

Copy link
Copy Markdown
Contributor

This is failing it's static check and I don't know how to decipher the error:

/Users/ash/code/airflow/airflow/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
97:21 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
122:27 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
/Users/ash/code/airflow/airflow/airflow/ui/src/queries/useLogs.tsx
43:59 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
50:7 error Unexpected use of continue statement no-continue
60:18 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
75:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
75:19 error Unsafe call of an `error` type typed value @typescript-eslint/no-unsafe-call
75:24 error Unsafe member access .map on an `error` typed value @typescript-eslint/no-unsafe-member-access
78:41 error Invalid type "unknown" of template literal expression @typescript-eslint/restrict-template-expressions
81:14 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment
86:5 error Unsafe assignment of an error typed value @typescript-eslint/no-unsafe-assignment

It's a bunch of typescript issues. Usually easier to read inline. We we weren't setting the types of the log parsing functions so that made typescript say every variable assignment in the function was unsafe.

Comment threadairflow/api_fastapi/core_api/routes/public/log.py
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 5 times, most recently from 6171d88 to b609dc3CompareFebruary 20, 2025 09:36
@Lee-WLee-W added the legacy api Whether legacy API changes should be allowed in PR label Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 527596d to b609dc3CompareFebruary 20, 2025 09:51
@Lee-WLee-W added the legacy ui Whether legacy UI change should be allowed in PR label Feb 20, 2025
@Lee-WLee-W closed this Feb 20, 2025
@Lee-WLee-W reopened this Feb 20, 2025
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from 6c41902 to 4bc68d4CompareFebruary 20, 2025 13:56
@Lee-W

Copy link
Copy Markdown
Member

quick update on the current progress. core tests should already be fixed. some provider ones remaining.

  • providers/amazon/tests/unit/amazon/aws/log/test_cloudwatch_task_handler.py
  • providers/amazon/tests/unit/amazon/aws/log/test_s3_task_handler.py
  • providers/google/tests/unit/google/cloud/log/test_gcs_task_handler.py
  • providers/elasticsearch/tests/unit/elasticsearch/log/test_es_task_handler.py

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch 3 times, most recently from dd1c677 to a612ff7CompareFebruary 21, 2025 09:21
@Lee-W

Copy link
Copy Markdown
Member

just add compat code to providers. The tests should pass now... I think...

@Lee-W

Lee-W commented Feb 21, 2025

Copy link
Copy Markdown
Member

didn't notice there're some others...

  • providers/microsoft/azure/tests/unit/microsoft/azure/log/test_wasb_task_handler.py::TestWasbTaskHandler::test_wasb_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_patterns_no_match
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_missing_logs
  • providers/opensearch/tests/unit/opensearch/log/test_os_task_handler.py::TestOpensearchTaskHandler::test_read_with_none_metadata
  • providers/redis/tests/unit/redis/log/test_redis_task_handler.py::TestRedisTaskHandler::test_read

@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from a612ff7 to a416611CompareFebruary 21, 2025 10:00
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from 1495cfd to ba1049eCompareFebruary 26, 2025 10:35
ashband others added 19 commits February 27, 2025 14:51
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
@Lee-W
Lee-Wforce-pushed the render-json-logs-new-ui branch from ba1049e to d3e2dffCompareFebruary 27, 2025 06:52
@Lee-W

Copy link
Copy Markdown
Member

As the comments are resolved, I'll merge this one. Thanks all for your help!

@Lee-W
Lee-W merged commit aa61371 into mainFeb 27, 2025
@bbovenzi
bbovenzi deleted the render-json-logs-new-ui branch February 27, 2025 14:43
ambika-garg pushed a commit to ambika-garg/airflow that referenced this pull request Feb 28, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
aaron-y-chen pushed a commit to aaron-y-chen/airflow that referenced this pull request Apr 4, 2025
…ache#46827)
* Render structured logs in the new UI rather than showing raw JSON
There are multiple parts to this PR;
First off: the log reader interface was _a mess_ There was some odd+old code
do deal with reading from multiple hosts that made the message confusing. This
was added for smart sensors (which went away in v2.4 or v2.5) but this mess
remained, and reading from multiple hosts is handled differently now.
This PR keeps the current "parse+interleave" behaviour (though it's debatable
if the interleave feature is needed specifically, or if we could get away with
a simpler concat instead. Future work there if anyone wants to think about and
tackle this.) but changes the JSON resposne type from a single string (the
value of which was previoulsy a mess of double encoded JSON and repr of a
python tuple making it impossible to do anything but display at) to a list of
either strings (when it can't be parsed) or a list of
dicts/StructuredLogMessage.
I have also done some cursory rendering/displaying of these structured log
messages in the UI, but they could be greatly improved by adding colors to
various components of the log.
The current rendered HTML looks like this:
```html
<p><span class="event">::group::Log message source details</span> <span class="log-key sources">sources=["/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log","/root/airflow/logs/dag_id=trigger_test/run_id=manual__2025-02-16T12:23:29.118614+00:00_gOTl0Qub/task_id=waiter/attempt=1.log.trigger.14.log"]</span></p>
<p><span class="event">::endgroup::</span></p>
<p>[<time datetime="2025-02-16T12:23:30.033308">2025-02-16T12:23:30.033308</time>] <span class="log-level debug">DEBUG</span> - <span class="event">Hook impls: []</span> <span class="log-key logger">logger="airflow.listeners.listener"</span></p>
```
Although not used by the UI, the non-application/json content type is now
updated to a) include the continuation token as a header, and to set the
content type as application/x-ndjson
* Fix typescript useLogs
* style: group metadata pop
* style: reduce if-else and directly use bool for assigning metadata["download_logs"]
* style: improve type annotation
* test(test_log_reader): fix existing unit tests
* test(api_fastapi): fix existing test_log unit tests
* feat(api_connexion/log): update v1 api to the latest log format
* test(providers/elasticsearch): fix part of the existing unit test
* test(providers/amazon): fix TestCloudwatchTaskHandler::test_read
* feat(providers/amazon): add airflow 3 compat logic
* feat(providers/google): add airflow 3 task handler log handling logic
* feat(providers/elasticsearch): add airflow 3 task handler log handling logic
* feat(providers/microsoft): add airflow 3 task handler log handling logic
* feat(providers/redis): add airflow 3 task handler log handling logic
* feat(providers/opensearch): add airflow 3 task handler log handling logic
* test: ignore unneeded tests
* test(log_handlers): fix pendulum.tz version imcompat
* feat: force StructuredLogMessage check when initialing
---------
Co-authored-by: Brent Bovenzi <brent.bovenzi@gmail.com>
Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:loggingarea:UIRelated to UI/UX. For Frontend Developers.legacy apiWhether legacy API changes should be allowed in PRlegacy uiWhether legacy UI change should be allowed in PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AIP-84 | Get Logs - Improve the formatting of the content response

6 participants

@ashb@bbovenzi@Lee-W@pierrejeambrun@jason810496@phanikumv