Improve std/log performance (#15614)

<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->
closes #15610 .

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->

This PR attempts to improve the performance of `std/log *` by making the
following changes:
1. use explicit piping instead of `reduce` for constructing the log
message
2. constify `log-level`, `log-ansi`, `log-types` etc.
3. use `.` instead of `get` to access `$env` fields


# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

Nothing.

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the
tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->

---------

Co-authored-by: Ben Yang <ben@ya.ng>
Co-authored-by: suimong <suimong@users.noreply.github.com>
This commit is contained in:
suimong 2025-04-23 02:00:20 +08:00 committed by GitHub
parent 1db4be12d1
commit e1ffaf2548
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,80 +1,79 @@
export def log-ansi [] { const LOG_ANSI = {
{ "CRITICAL": (ansi red_bold),
"CRITICAL": (ansi red_bold), "ERROR": (ansi red),
"ERROR": (ansi red), "WARNING": (ansi yellow),
"WARNING": (ansi yellow), "INFO": (ansi default),
"INFO": (ansi default), "DEBUG": (ansi default_dimmed)
"DEBUG": (ansi default_dimmed)
}
} }
export def log-level [] { export def log-ansi [] {$LOG_ANSI}
{
"CRITICAL": 50, const LOG_LEVEL = {
"ERROR": 40, "CRITICAL": 50,
"WARNING": 30, "ERROR": 40,
"INFO": 20, "WARNING": 30,
"DEBUG": 10 "INFO": 20,
} "DEBUG": 10
} }
export def log-prefix [] {
{ export def log-level [] {$LOG_LEVEL}
"CRITICAL": "CRT",
"ERROR": "ERR", const LOG_PREFIX = {
"WARNING": "WRN", "CRITICAL": "CRT",
"INFO": "INF", "ERROR": "ERR",
"DEBUG": "DBG" "WARNING": "WRN",
} "INFO": "INF",
"DEBUG": "DBG"
} }
export def log-short-prefix [] {
{ export def log-prefix [] {$LOG_PREFIX}
"CRITICAL": "C",
"ERROR": "E", const LOG_SHORT_PREFIX = {
"WARNING": "W", "CRITICAL": "C",
"INFO": "I", "ERROR": "E",
"DEBUG": "D" "WARNING": "W",
} "INFO": "I",
"DEBUG": "D"
} }
export def log-short-prefix [] {$LOG_SHORT_PREFIX}
export-env { export-env {
$env.NU_LOG_FORMAT = $env.NU_LOG_FORMAT? | default "%ANSI_START%%DATE%|%LEVEL%|%MSG%%ANSI_STOP%" $env.NU_LOG_FORMAT = $env.NU_LOG_FORMAT? | default "%ANSI_START%%DATE%|%LEVEL%|%MSG%%ANSI_STOP%"
$env.NU_LOG_DATE_FORMAT = $env.NU_LOG_DATE_FORMAT? | default "%Y-%m-%dT%H:%M:%S%.3f" $env.NU_LOG_DATE_FORMAT = $env.NU_LOG_DATE_FORMAT? | default "%Y-%m-%dT%H:%M:%S%.3f"
} }
def log-types [] { const LOG_TYPES = {
( "CRITICAL": {
{ "ansi": $LOG_ANSI.CRITICAL,
"CRITICAL": { "level": $LOG_LEVEL.CRITICAL,
"ansi": (log-ansi).CRITICAL, "prefix": $LOG_PREFIX.CRITICAL,
"level": (log-level).CRITICAL, "short_prefix": $LOG_SHORT_PREFIX.CRITICAL
"prefix": (log-prefix).CRITICAL, },
"short_prefix": (log-short-prefix).CRITICAL "ERROR": {
}, "ansi": $LOG_ANSI.ERROR,
"ERROR": { "level": $LOG_LEVEL.ERROR,
"ansi": (log-ansi).ERROR, "prefix": $LOG_PREFIX.ERROR,
"level": (log-level).ERROR, "short_prefix": $LOG_SHORT_PREFIX.ERROR
"prefix": (log-prefix).ERROR, },
"short_prefix": (log-short-prefix).ERROR "WARNING": {
}, "ansi": $LOG_ANSI.WARNING,
"WARNING": { "level": $LOG_LEVEL.WARNING,
"ansi": (log-ansi).WARNING, "prefix": $LOG_PREFIX.WARNING,
"level": (log-level).WARNING, "short_prefix": $LOG_SHORT_PREFIX.WARNING
"prefix": (log-prefix).WARNING, },
"short_prefix": (log-short-prefix).WARNING "INFO": {
}, "ansi": $LOG_ANSI.INFO,
"INFO": { "level": $LOG_LEVEL.INFO,
"ansi": (log-ansi).INFO, "prefix": $LOG_PREFIX.INFO,
"level": (log-level).INFO, "short_prefix": $LOG_SHORT_PREFIX.INFO
"prefix": (log-prefix).INFO, },
"short_prefix": (log-short-prefix).INFO "DEBUG": {
}, "ansi": $LOG_ANSI.DEBUG,
"DEBUG": { "level": $LOG_LEVEL.DEBUG,
"ansi": (log-ansi).DEBUG, "prefix": $LOG_PREFIX.DEBUG,
"level": (log-level).DEBUG, "short_prefix": $LOG_SHORT_PREFIX.DEBUG
"prefix": (log-prefix).DEBUG, }
"short_prefix": (log-short-prefix).DEBUG
}
}
)
} }
def parse-string-level [ def parse-string-level [
@ -82,16 +81,16 @@ def parse-string-level [
] { ] {
let level = ($level | str upcase) let level = ($level | str upcase)
if $level in [(log-prefix).CRITICAL (log-short-prefix).CRITICAL "CRIT" "CRITICAL"] { if $level in [$LOG_PREFIX.CRITICAL $LOG_SHORT_PREFIX.CRITICAL "CRIT" "CRITICAL"] {
(log-level).CRITICAL $LOG_LEVEL.CRITICAL
} else if $level in [(log-prefix).ERROR (log-short-prefix).ERROR "ERROR"] { } else if $level in [$LOG_PREFIX.ERROR $LOG_SHORT_PREFIX.ERROR "ERROR"] {
(log-level).ERROR $LOG_LEVEL.ERROR
} else if $level in [(log-prefix).WARNING (log-short-prefix).WARNING "WARN" "WARNING"] { } else if $level in [$LOG_PREFIX.WARNING $LOG_SHORT_PREFIX.WARNING "WARN" "WARNING"] {
(log-level).WARNING $LOG_LEVEL.WARNING
} else if $level in [(log-prefix).DEBUG (log-short-prefix).DEBUG "DEBUG"] { } else if $level in [$LOG_PREFIX.DEBUG $LOG_SHORT_PREFIX.DEBUG "DEBUG"] {
(log-level).DEBUG $LOG_LEVEL.DEBUG
} else { } else {
(log-level).INFO $LOG_LEVEL.INFO
} }
} }
@ -99,41 +98,41 @@ def parse-int-level [
level: int, level: int,
--short (-s) --short (-s)
] { ] {
if $level >= (log-level).CRITICAL { if $level >= $LOG_LEVEL.CRITICAL {
if $short { if $short {
(log-short-prefix).CRITICAL $LOG_SHORT_PREFIX.CRITICAL
} else { } else {
(log-prefix).CRITICAL $LOG_PREFIX.CRITICAL
} }
} else if $level >= (log-level).ERROR { } else if $level >= $LOG_LEVEL.ERROR {
if $short { if $short {
(log-short-prefix).ERROR $LOG_SHORT_PREFIX.ERROR
} else { } else {
(log-prefix).ERROR $LOG_PREFIX.ERROR
} }
} else if $level >= (log-level).WARNING { } else if $level >= $LOG_LEVEL.WARNING {
if $short { if $short {
(log-short-prefix).WARNING $LOG_SHORT_PREFIX.WARNING
} else { } else {
(log-prefix).WARNING $LOG_PREFIX.WARNING
} }
} else if $level >= (log-level).INFO { } else if $level >= $LOG_LEVEL.INFO {
if $short { if $short {
(log-short-prefix).INFO $LOG_SHORT_PREFIX.INFO
} else { } else {
(log-prefix).INFO $LOG_PREFIX.INFO
} }
} else { } else {
if $short { if $short {
(log-short-prefix).DEBUG $LOG_SHORT_PREFIX.DEBUG
} else { } else {
(log-prefix).DEBUG $LOG_PREFIX.DEBUG
} }
} }
} }
def current-log-level [] { def current-log-level [] {
let env_level = ($env.NU_LOG_LEVEL? | default (log-level).INFO) let env_level = ($env.NU_LOG_LEVEL? | default $LOG_LEVEL.INFO)
try { try {
$env_level | into int $env_level | into int
@ -188,7 +187,7 @@ export def critical [
--format (-f): string # A format (for further reference: help std log) --format (-f): string # A format (for further reference: help std log)
] { ] {
let format = $format | default "" let format = $format | default ""
handle-log $message (log-types | get CRITICAL) $format $short handle-log $message ($LOG_TYPES.CRITICAL) $format $short
} }
# Log an error message # Log an error message
@ -198,7 +197,7 @@ export def error [
--format (-f): string # A format (for further reference: help std log) --format (-f): string # A format (for further reference: help std log)
] { ] {
let format = $format | default "" let format = $format | default ""
handle-log $message (log-types | get ERROR) $format $short handle-log $message ($LOG_TYPES.ERROR) $format $short
} }
# Log a warning message # Log a warning message
@ -208,7 +207,7 @@ export def warning [
--format (-f): string # A format (for further reference: help std log) --format (-f): string # A format (for further reference: help std log)
] { ] {
let format = $format | default "" let format = $format | default ""
handle-log $message (log-types | get WARNING) $format $short handle-log $message ($LOG_TYPES.WARNING) $format $short
} }
# Log an info message # Log an info message
@ -218,7 +217,7 @@ export def info [
--format (-f): string # A format (for further reference: help std log) --format (-f): string # A format (for further reference: help std log)
] { ] {
let format = $format | default "" let format = $format | default ""
handle-log $message (log-types | get INFO) $format $short handle-log $message ($LOG_TYPES.INFO) $format $short
} }
# Log a debug message # Log a debug message
@ -228,7 +227,7 @@ export def debug [
--format (-f): string # A format (for further reference: help std log) --format (-f): string # A format (for further reference: help std log)
] { ] {
let format = $format | default "" let format = $format | default ""
handle-log $message (log-types | get DEBUG) $format $short handle-log $message ($LOG_TYPES.DEBUG) $format $short
} }
def log-level-deduction-error [ def log-level-deduction-error [
@ -242,7 +241,7 @@ def log-level-deduction-error [
text: ([ text: ([
"Invalid log level." "Invalid log level."
$" Available log levels in log-level:" $" Available log levels in log-level:"
(log-level | to text | lines | each {|it| $" ($it)" } | to text) ($LOG_LEVEL | to text | lines | each {|it| $" ($it)" } | to text)
] | str join "\n") ] | str join "\n")
span: $span span: $span
} }
@ -262,11 +261,11 @@ export def custom [
} }
let valid_levels_for_defaulting = [ let valid_levels_for_defaulting = [
(log-level).CRITICAL $LOG_LEVEL.CRITICAL
(log-level).ERROR $LOG_LEVEL.ERROR
(log-level).WARNING $LOG_LEVEL.WARNING
(log-level).INFO $LOG_LEVEL.INFO
(log-level).DEBUG $LOG_LEVEL.DEBUG
] ]
let prefix = if ($level_prefix | is-empty) { let prefix = if ($level_prefix | is-empty) {
@ -280,7 +279,7 @@ export def custom [
$level_prefix $level_prefix
} }
let use_color = ($env | get config? | get use_ansi_coloring? | $in != false) let use_color = ($env.config?.use_ansi_coloring? | $in != false)
let ansi = if not $use_color { let ansi = if not $use_color {
"" ""
} else if ($ansi | is-empty) { } else if ($ansi | is-empty) {
@ -289,7 +288,7 @@ export def custom [
} }
( (
log-types $LOG_TYPES
| values | values
| each {|record| | each {|record|
if ($record.level == $log_level) { if ($record.level == $log_level) {
@ -301,19 +300,19 @@ export def custom [
$ansi $ansi
} }
print --stderr ([ print --stderr (
["%MSG%" $message] $format
["%DATE%" (now)] | str replace --all "%MSG%" $message
["%LEVEL%" $prefix] | str replace --all "%DATE%" (now)
["%ANSI_START%" $ansi] | str replace --all "%LEVEL%" $prefix
["%ANSI_STOP%" (ansi reset)] | str replace --all "%ANSI_START%" $ansi
] | reduce --fold $format { | str replace --all "%ANSI_STOP%" (ansi reset)
|it, acc| $acc | str replace --all $it.0 $it.1
}) )
} }
def "nu-complete log-level" [] { def "nu-complete log-level" [] {
log-level | transpose description value $LOG_LEVEL | transpose description value
} }
# Change logging level # Change logging level