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