Code Monkey home page Code Monkey logo

hl's Introduction

hl Build Status Coverage Status

A fast and powerful log viewer and processor that translates JSON or logfmt logs into a pretty human-readable format. High performance and convenient features are the main goals.

Features overview

  • Automatic usage of the less pager by default for convenience.
  • Log streaming with the -P flag that disables the pager.
  • Log record filtering by field key/value pairs with the -f option with support for hierarchical keys.
  • Quick and easy filtering by level with the -l option.
  • Quick and easy filtering by timestamp range using the --since and --until options and intuitive formats:
    • RFC-3339 timestamp format.
    • Current configured timestamp output format with the -t option or environment variable.
    • Human friendly shortcuts like today, yesterday, friday or relative offsets like -3h or -14d.
  • Quick and easy hiding and revealing of fields with the -h option.
  • Hide empty fields with the -e flag.
  • Lightning fast message sorting with automatic indexing for local files using the -s flag.
    • Handles ~1 GiB/s for the first scan and allows fast filtering by timestamp range and level without scanning the data afterwards.
    • Works fast with hundreds of local files containing hundreds of gigabytes of data.
    • Reindexes large, growing files at lightning speed, skipping unmodified blocks, ~10 GiB/s.
  • Follow mode with live message sorting by timestamp from different sources using the -F flag and preview of several recent messages with the --tail option.
  • Custom complex queries that can include and/or conditions and much more.
  • Non-JSON prefixes with --allow-prefix flag.
  • Displays timestamps in UTC by default and supports easy timezone switching with the -Z option and the -L flag for a local timezone.
  • Customizable via configuration file and environment variables, supports easy theme switching and custom themes.

Performance comparison chart

Performance comparison with humanlog, hlogf and fblog on a 2.3 GiB log file

performance chart

Installation options

  • Install using homebrew on macOS or Linux

    brew install pamburus/tap/hl
    
  • Download and extract using curl and tar on macOS

    curl -sSfL https://github.com/pamburus/hl/releases/latest/download/hl-macos.tar.gz | tar xz
    
  • Download and extract using curl and tar on Linux

    curl -sSfL https://github.com/pamburus/hl/releases/latest/download/hl-linux-x86_64-musl.tar.gz | tar xz
    
  • Install AUR package on Arch Linux

    yay -S hl-log-viewer-bin
    
  • Install using cargo

    cargo install --locked --git https://github.com/pamburus/hl.git
    
  • Download latest release from download page

Examples

Screenshot

screenshot-light screenshot-dark

See other screenshots

Features and usage

Concatenation of multiple log files

  • Concatenate all log files

    Command

    $ hl $(ls -tr /var/log/example/*.log)
    

    Concatenates and humanizes all *.log files found in /var/log/example/.

Support for gzipped log files

  • Concatenate all log files including gzipped log files

    Command

    $ hl $(ls -tr /var/log/example/*.{log,log.gz})
    

    Concatenates and humanizes all *.log and *.log.gz files found in /var/log/example/.

Automatic usage of pager

  • Use default pager with default parameters

    Command

    $ hl example.log
    

    Automatically opens less pager with default parameters.

  • Override options for default pager

    Command

    $ LESS=-SR hl example.log
    

    Opens less pager with disabled line wrapping.

  • Use custom pager

    Command

    $ PAGER=bat hl example.log
    

    Opens bat pager.

Quick filtering by log level

  • Errors only

    Command

    $ hl -l e
    

    Displays only error log level messages.

  • Errors and warnings

    Command

    $ hl -l w
    

    Displays only warning and error log level messages.

  • Errors, warnings and informational

    Command

    $ hl -l i
    

    Displays all log messages except debug level messages.

Using live log streaming

  • Command

    $ tail -f example.log | hl -P
    

    Tracks changes in the example.log file and displays them immediately. Flag -P disables automatic using of pager in this case.

Filtering by field values

  • Command

    $ hl example.log --filter component=tsdb
    

    Displays only messages where the component field has the value tsdb.

  • Command

    $ hl example.log -f component!=tsdb -f component!=uninteresting
    

    Displays only messages where the component field has a value other than tsdb or uninteresting.

  • Command

    $ hl example.log -f provider~=string
    

    Displays only messages where the provider field contains the string sub-string.

  • Command

    $ hl example.log -f 'provider!~=string'
    

    Displays only messages where the provider field does not contain the string sub-string.

Performing complex queries

  • Command

    $ hl my-service.log --query 'level > info or status-code >= 400 or duration > 0.5'
    

    Displays messages that either have a level higher than info (i.e. warning or error) or have a status code field with a numeric value >= 400 or a duration field with a numeric value >= 0.5.

  • Command

    $ hl my-service.log -q '(request in (95c72499d9ec, 9697f7aa134f, bc3451d0ad60)) or (method != GET)'
    

    Displays all messages that have the 'request' field with one of these values, or the 'method' field with a value other than 'GET'.

  • Complete set of supported operators

    • Logical operators
      • Logical conjunction - and, &&
      • Logical disjunction - or, ||
      • Logical negation - not, !
    • Comparison operators
      • Equal - eq, =
      • Not equal - ne, !=
      • Greater than - gt, >
      • Greater or equal - ge, >=
      • Less than - lt, <
      • Less or equal - le, <=
    • String matching operators
      • Sub-string check - (contain, ~=), (not contain, !~=)
      • Wildcard match - (like), (not like)
        • Wildcard characters are: * for zero or more characters and ? for a single character
      • Regular expression match - (match, ~~=), (not match, !~~=)
    • Operators with sets
      • Test if value is one of the values in a set - in (v1, v2), not in (v1, v2)
      • Test if value is one of the values in a set loaded from a file - in @filename, not in @filename, assuming that each element is a line in the file, which can be either a simple string or a JSON string
      • Test if value is one of the values in a set loaded stdin - in @-, not in @-
  • Notes

    • Special field names that are reserved for filtering by predefined fields regardless of the actual source field names used to load the corresponding value: level, message, caller and logger.
    • To address a source field with one of these names instead of predefined fields, add a period before its name, i.e., .level will perform a match against the "level" source field.
    • To address a source field by its exact name, use a JSON-formatted string, i.e. -q '".level" = info'.
    • To specify special characters in field values, also use a JSON-formatted string, i.e.
      $ hl my-service.log -q 'message contain "Error:\nSomething unexpected happened"'
      

Filtering by time range

  • Command

    $ hl example.log --since 'Jun 19 11:22:33' --until yesterday
    

    Displays only messages that occurred after Jun 19 11:22:33 UTC of the current year (or the previous year if the current date is less than Jun 19 11:22:33) and before yesterday midnight.

  • Command

    $ hl example.log --since -3d
    

    Displays only messages from the past 72 hours.

  • Command

    $ hl example.log --until '2021-06-01 18:00:00' --local
    

    Displays only messages that occurred before 6 PM local time on June 1, 2021, and shows timestamps in local time.

Hiding or revealing selected fields

  • Command

    $ hl example.log --hide provider
    

    Hides field provider.

  • Command

    $ hl example.log --hide '*' --hide '!provider'
    

    Hides all fields except provider.

  • Command

    $ hl example.log -h headers -h body -h '!headers.content-type'
    

    Hides fields headers and body but shows a single sub-field content-type inside field headers.

Sorting messages chronologically

  • Command

    $ hl -s *.log
    

    Displays log messages from all log files in the current directory sorted in chronological order.

Sorting messages chronologically with following the changes

  • Command

    $ hl --sync-interval-ms 500 -F <(kubectl logs -l app=my-app-1 -f) <(kubectl logs -l app=my-app-2 -f)
    

    Runs without a pager in follow mode by merging messages from the outputs of these 2 commands and sorting them chronologically within a custom 500ms interval.

  • Command

    $ hl -F --tail 100 app1.log app2.log app3.log
    

    Runs without a pager in follow mode, following the changes in three log files in the current directory and sorting them chronologically at a default interval of 100ms. Preloads 100 lines from the end of each file before filtering.

Configuration files

  • Configuration file is automatically loaded if found in a predefined platform-specific location.

    OS Location
    macOS ~/.config/hl/config.{yaml,toml,json}
    Linux ~/.config/hl/config.{yaml,toml,json}
    Windows %USERPROFILE%\AppData\Roaming\hl\config.{yaml,toml,json}
  • The path to the configuration file can be overridden using the HL_CONFIG environment variable.

  • All parameters in the configuration file are optional and can be omitted. In this case, default values are used.

Default configuration file

Environment variables

  • Many parameters that are defined in command line arguments and configuration files can also be specified by environment variables.

Precedence of configuration sources (from lowest priority to highest priority)

  • Configuration file
  • Environment variables
  • Command-line arguments

Examples

  • HL_TIME_FORMAT='%y-%m-%d %T.%3N' overrides the time format specified in the configuration file.
  • HL_TIME_ZONE=Europe/Berlin overrides the time zone specified in the configuration file.
  • HL_CONCURRENCY=4 overrides the concurrency limit specified in the configuration file.
  • HL_PAGING=never specifies the default value for the paging option, but it can be overridden by command line arguments.

Themes

Stock themes

Selecting current theme

  • Using theme value in the configuration file.
  • Using environment variable, i.e. HL_THEME=classic, overrides the value specified in configuration file.
  • Using command-line argument, i.e. --theme classic, overrides all other values.

Selecting themes with preview

To select themes with preview fzf tool can be used like this:

hl --list-themes | fzf --preview-window="top,80%" --preview="head -n 100 example.log | hl -c --theme {}"

Custom themes

  • Custom themes are automatically loaded when found in a predefined platform-specific location.

    OS Location
    macOS ~/.config/hl/themes/*.{yaml,toml,json}
    Linux ~/.config/hl/themes/*.{yaml,toml,json}
    Windows %USERPROFILE%\AppData\Roaming\hl\themes*.{yaml,toml,json}
  • Format description

    • Section elements contains styles for predefined elements.
    • Section levels contains optional overrides for styles defined in elements sections per logging level, which are [debug, info, warning, error].
    • Each element style contains optional background, foreground and modes parameters.
    • Example
      elements:
          <element>:
              foreground: <color>
              background: <color>
              modes: [<mode>, <mode>, ...]
      levels:
          <level>:
              <element>:
                  foreground: <color>
                  background: <color>
                  modes: [<mode>, <mode>, ...]
    • Color format is one of
      • Keyword default specifies default color defined by the terminal.
      • ASCII basic color name, one of
        • black
        • red
        • green
        • yellow
        • blue
        • magenta
        • cyan
        • white
        • bright-black
        • bright-red
        • bright-green
        • bright-yellow
        • bright-blue
        • bright-magenta
        • bright-cyan
        • bright-white
      • 256-color palette code, from 0 to 255.
      • RGB color in hex web color format, i.e. #FFFF00 for bright yellow color.
    • Modes is a list of additional styles, each of them is one of
      • bold
      • faint
      • italic
      • underline
      • slow-blink
      • rapid-blink
      • reverse
      • conceal
      • crossed-out

Used terminal color schemes

iTerm2

Alacritty

  • One Dark Neo
    • Note: It is recommended to use draw_bold_text_with_bright_colors: true setting
  • Light
    • Note: It is recommended to use draw_bold_text_with_bright_colors: false setting

Complete set of options and flags

JSON and logfmt log converter to human readable representation

Usage: hl [OPTIONS] [FILE]...

Arguments:
  [FILE]...  Files to process

Options:
      --config <FILE>                    Configuration file path [env: HL_CONFIG=]
  -s, --sort                             Sort messages chronologically
  -F, --follow                           Follow input streams and sort messages chronologically during time frame set by --sync-interval-ms option
      --tail <N>                         Number of last messages to preload from each file in --follow mode [default: 10]
      --sync-interval-ms <MILLISECONDS>  Synchronization interval for live streaming mode enabled by --follow option [default: 100]
      --paging <WHEN>                    Control pager usage (HL_PAGER or PAGER) [env: HL_PAGING=] [default: auto] [possible values: auto, always, never]
  -P                                     Handful alias for --paging=never, overrides --paging option
      --help                             Print help
  -V, --version                          Print version

Filtering Options:
  -l, --level <LEVEL>    Filter messages by level [env: HL_LEVEL=]
      --since <TIME>     Filter messages by timestamp >= <TIME> (--time-zone and --local options are honored)
      --until <TIME>     Filter messages by timestamp <= <TIME> (--time-zone and --local options are honored)
  -f, --filter <FILTER>  Filter messages by field values [k=v, k~=v, k~~=v, 'k!=v', 'k!~=v', 'k!~~=v'] where ~ does substring match and ~~ does regular expression match
  -q, --query <QUERY>    Filter using query, accepts expressions from --filter and supports '(', ')', 'and', 'or', 'not', 'in', 'contain', 'like', '<', '>', '<=', '>=', etc

Output Options:
      --color [<WHEN>]        Color output control [env: HL_COLOR=] [default: auto] [possible values: auto, always, never]
  -c                          Handful alias for --color=always, overrides --color option
      --theme <THEME>         Color theme [env: HL_THEME=] [default: universal]
  -r, --raw                   Output raw source messages instead of formatted messages, which can be useful for applying filters and saving results in their original format
      --no-raw                Disable raw source messages output, overrides --raw option
      --raw-fields            Output field values as is, without unescaping or prettifying
  -h, --hide <KEY>            Hide or reveal fields with the specified keys, prefix with ! to reveal, specify '!*' to reveal all
      --flatten <WHEN>        Whether to flatten objects [env: HL_FLATTEN=] [default: always] [possible values: never, always]
  -t, --time-format <FORMAT>  Time format, see https://man7.org/linux/man-pages/man1/date.1.html [env: HL_TIME_FORMAT=] [default: "%b %d %T.%3N"]
  -Z, --time-zone <TZ>        Time zone name, see column "TZ identifier" at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones [env: HL_TIME_ZONE=] [default: UTC]
  -L, --local                 Use local time zone, overrides --time-zone option
      --no-local              Disable local time zone, overrides --local option
  -e, --hide-empty-fields     Hide empty fields, applies for null, string, object and array fields only [env: HL_HIDE_EMPTY_FIELDS=]
  -E, --show-empty-fields     Show empty fields, overrides --hide-empty-fields option [env: HL_SHOW_EMPTY_FIELDS=]
      --input-info <VARIANT>  Show input number and/or input filename before each message [default: auto] [possible values: auto, none, full, compact, minimal]
  -o, --output <FILE>         Output file

Input Options:
      --input-format <FORMAT>       Input format [env: HL_INPUT_FORMAT=] [default: auto] [possible values: auto, json, logfmt]
      --unix-timestamp-unit <UNIT>  Unix timestamp unit [env: HL_UNIX_TIMESTAMP_UNIT=] [default: auto] [possible values: auto, s, ms, us, ns]
      --allow-prefix                Allow non-JSON prefixes before JSON messages [env: HL_ALLOW_PREFIX=]
      --delimiter <DELIMITER>       Log message delimiter, [NUL, CR, LF, CRLF] or any custom string

Advanced Options:
      --interrupt-ignore-count <N>  Number of interrupts to ignore, i.e. Ctrl-C (SIGINT) [env: HL_INTERRUPT_IGNORE_COUNT=] [default: 3]
      --buffer-size <SIZE>          Buffer size [env: HL_BUFFER_SIZE=] [default: "256 KiB"]
      --max-message-size <SIZE>     Maximum message size [env: HL_MAX_MESSAGE_SIZE=] [default: "64 MiB"]
  -C, --concurrency <N>             Number of processing threads [env: HL_CONCURRENCY=]
      --shell-completions <SHELL>   Print shell auto-completion script and exit [possible values: bash, elvish, fish, powershell, zsh]
      --man-page                    Print man page and exit
      --list-themes                 Print available themes and exit
      --dump-index                  Print debug index metadata (in --sort mode) and exit
      --debug                       Print debug error messages that can help with troubleshooting

Performance

performance chart

  • MacBook Pro (16-inch, 2021)
    • CPU: Apple M1 Max CPU
    • OS: macOS Sonoma 14.4.1
    • Data: ~ 2.3 GiB log file, 6 000 000 lines
      • hl v0.28.0 ~ 1.4 seconds

        $ time hl example.log -c -o /dev/null
        hl example.log -c -o /dev/null  11.74s user 0.53s system 885% cpu 1.386 total
        
      • hlogf v1.4.1 ~ 8.5 seconds

        $ time hlogf example.log --color always >/dev/null
        hlogf example.log --color always > /dev/null  6.93s user 1.79s system 99% cpu 8.757 total
        
      • humanlog v0.7.6 ~ 77 seconds

        $ time humanlog <example.log --color always >/dev/null
        humanlog> reading stdin...
        humanlog --color always < example.log > /dev/null  80.02s user 4.71s system 109% cpu 1:17.11 total
        
      • fblog v4.9.0 ~ 36 seconds

        $ time fblog example.log >/dev/null
        fblog example.log > /dev/null  32.48s user 2.03s system 97% cpu 35.526 total
        
      • fblog with -d flag v4.9.0 ~ 148 seconds

        $ time fblog -d example.log >/dev/null
        fblog -d example.log > /dev/null  132.12s user 14.39s system 99% cpu 2:27.61 total
        
    • See #132 for how to repeat measurements

hl's People

Contributors

actions-user avatar dependabot[bot] avatar jellyfrog avatar k2s avatar pamburus avatar qqshfox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

hl's Issues

Support syslog prefix

Below is an example format from our service, which logs to syslog and got some prefix:

Dec 12 02:20:57 abc.def myserver[12606]: {"level":"info","action":"LOGIN","clientId":"myserver:v1.2.3","deviceId":"abcd", "msg":"login succeeded"}

It would be nice if hl can leave the prefix part as is and format the json part, like what jl does

With `jl':

echo 'Dec 12 02:20:57 abc.def myserver[12606]: {"level":"info","action":"LOGIN","clientId":"myserver:v1.2.3","deviceId":"abcd", "msg":"login succeeded"}' | jl
Dec 12 02:20:57 abc.def myserver[12606]:    INFO: login succeeded [action=LOGIN clientId=myserver:v1.2.3 deviceId=abcd]

With hl:

echo 'Dec 12 02:20:57 abc.def myserver[12606]: {"level":"info","action":"LOGIN","clientId":"myserver:v1.2.3","deviceId":"abcd", "msg":"login succeeded"}' | hl -P
Dec 12 02:20:57 abc.def myserver[12606]: {"level":"info","action":"LOGIN","clientId":"myserver:v1.2.3","deviceId":"abcd", "msg":"login succeeded"}

ASCII Colors in Message Supported?

Is ASCII color decoding supported in hl if it is in the message? I know this worked for me at some point.

Command

hl --color always filename.log --since -1d

Output in Terminal

Aug 19 04:04:07.798 PM EDT |INF| "[\u001b[1mINFO \u001b[0m] [\u001b[34mMainThread\u001b[0m] [\u001b[36m__init__.py         \u001b[0m:\u001b[36m1706\u001b[0m] \u001b[1mFinished processing state st_aws_job_standby exit callbacks.\u001b[0m"

Message duplicated if taken from nested field

Thanks for hl, it's a useful tool!

I'm dealing with a rather unfortunate log format where the message field is not located at the top level of the JSON object, but in a nested field. Luckily, hl supports reading the message from a nested field, but I found that it duplicates the message in the output while doing so. This does not happen if the message is in a top level field.

Case 1 (good)

Contents of good.json:

{"ts": "1711402897", "level": "info", "message": "test message", "field1": "value1"}

Command: hl good.json

Output:

Mar 25 21:41:37.000 |INF| test message field1=value1

This is what I'd expect to happen. The message is not shown as a field but is displayed right after the log level.

Case 2 (unexpected)

Contents of bad.json:

{"ts": "1711402897", "level": "info", "message": {"text": "test message", "nested1": "value2"}, "field1": "value1"}

Contents of config.yaml:

fields:
  predefined:
    message:
      names: [message.text]

Command: HL_CONFIG=config.yaml hl bad.json

Output:

Mar 25 21:41:37.000 |INF| test message message={ text=test message nested1=value2 } field1=value1

In this case, the message is correctly displayed after the log level, but I would not have expected it to also still be displayed in the fields.

I'm not sure if this is intended behavior, and if it isn't, whether it's even desirable to change this to avoid the duplication.

Add ability to set custom fields (time/level)

Some programs writes logs with custom field names. In my case, datetime field instead of time and level_name instead of level:

{"datetime":"2021-05-21T02:53:11+03:00","level_name":"info","message":"Rabbitmq connection created"}

And the hl output:

        ---         |(?)| Rabbitmq connection created datetime='2021-05-21T02:53:11+03:00' level-name='info'

Add support for logfmt

I would love to be able to use hl for logfmt logs.
Any chance this could be added as supported format?
For me, that's the only reason i keep using humanlog

Filter Support for Two or More Substrings

Is the following supported by having two filtered substrings?

./hl final.log -f message~=status -f container_name=datadog

I have it working if I only use one filter (each tested correctly by themselves) but when I combine both, the output is nothing. Trying to get logs for a container name with the word status in the message field.

Add support to merge logs with time ordering

Hi

It would be very useful if hl can merge logs based on time.
Those logs might comes from different component in a big system. In order to trace issues, having a time ordered a logs is very useful. Hopefully it can be supported in this tool

best regard

add "not containing sub-string"

There is hl example.log -f component=tsdb and its negation hl example.log -f component!=tsdb.

Then there is hl example.log -f provider~=string, but its negation doesn't work hl example.log -f provider!~=string.

Thank you.

How to show milliseconds since epoch human readable?

When configuring Kubernetes and components thereof to log in json format the standard is to put a timestamp in the field ts as float signifying milliseconds since epoch. For example 1710858913.7978325 for Tue Mar 19 14:35:13 2024 (UTC).

Can you make hl parse this and output a human readable time string? If yes, how?

Here is the responsible line of code: https://github.com/kubernetes/component-base/blob/9d90bf7eaa57df6d6e0dd316529274b3c5747f5f/logs/json/json.go#L71

Handle log level in kubernetes logs

Thank you for #154 , which improved parsing of kubernetes json logs: https://kubernetes.io/docs/concepts/cluster-administration/system-logs/#json-log-format

The remaining thing that would be nice to have addressed is level. As you can see above it is handled a bit differently.

Info

The presence of the field v means info. But a higher number is reasonable to interpret as debug.

So a variant for the level configuration could look like:

    - names: [v]
      values:
        debug: [2, 3, 4]
        info: [0,1]

Except that it doesn't work. Going back to the example I gave in #153:

{"ts":1710923450736.8257,"caller":"eligibility/eligibility.go:104","msg":"Scale-down calculation: ignoring 2 nodes unremovable in the last 5m0s\n","v":1}

For this with the configuration above hl still show (?) as level. But if I put the value of v in quotes, making it a string, it does work. I.e. with this example hl shows the log level as info:

{"ts":1710923450736.8257,"caller":"eligibility/eligibility.go:104","msg":"Scale-down calculation: ignoring 2 nodes unremovable in the last 5m0s\n","v":"1"}

So I propose support for converting field value and values in the configuration to a common type before comparison.

Error

An error in these logs is signified by the presence of the field err, the content of which you would also like to see. As far as I can see this is not possible to configure at the moment. So I propose a new feature to make the presence of a field indicate a level. Maybe the configuration could look like this:

    - names: [err]
      values:
        error: exists 

Non-string `caller-line` cannot be parsed

$ echo '{"filename": "whtvr", "lineno": 1}' | hl -P
        ---         |(?)| @ whtvr:

$ echo '{"filename": "whtvr", "lineno": "1"}' | hl -P
        ---         |(?)| @ whtvr:1

I tried making a PR but had to change the second type of FileLine to String, which doesn't look like it's the best way. First time diving into a rust codebase.

Please extend list of names of msg field

Hi, this little change (or similar) would make our life easier. Thank you for your work!

diff --git a/src/model.rs b/src/model.rs
index d209177..2a6fc94 100644
--- a/src/model.rs
+++ b/src/model.rs
@@ -159,7 +159,7 @@ impl<'de: 'a, 'a> Visitor<'de> for RecordVisitor<'a> {
                 "__REALTIME_TIMESTAMP" => {
                     rts = rts.or(Some(access.next_value()?));
                 }
-                "msg" | "MESSAGE" | "Message" => {
+                "msg" | "MESSAGE" | "Message" | "message" => {
                     message = access.next_value()?;
                 }
                 "level" | "LEVEL" | "Level" => {

Daylight Saving Time Support

I noticed if I put the timezone in EST and downloaded recent logs (within a couple of minutes). The hour is off by 1 because EST is on DST currently right now. Can this be corrected?

Support for ecs log format

It would be useful if hl had support for logs following the ECS standard:

https://www.elastic.co/guide/en/ecs/8.10/ecs-reference.html

Especially the general log related fields:

https://www.elastic.co/guide/en/ecs/8.10/ecs-log.html

As an example here is log line from a python application using the ecs_logging library (filtered through jq for readability):

{
  "@timestamp": "2023-11-02T08:09:10.423Z",
  "log.level": "info",
  "message": "backup for database bar in foo is already done today",
  "application": "backup-rds",
  "ecs": {
    "version": "1.6.0"
  },
  "language": "python",
  "log": {
    "logger": "__main__",
    "origin": {
      "file": {
        "line": 107,
        "name": "app.py"
      },
      "function": "is_backup_done"
    },
    "original": "backup for database bar in foo is already done today"
  },
  "process": {
    "name": "MainProcess",
    "pid": 1,
    "thread": {
      "id": 140610736142144,
      "name": "MainThread"
    }
  }
}

Adding support for log.level is just a matter of adding the field name log.level to fileds.predefined.logger.names in config.yaml. But I have also tried to add caller information, but as far as I can see it is not possible to specify nested fields as predefined fields.

I'm using version 0.20.0-beta.14.9 of hl.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.