{"id":19030327,"url":"https://github.com/chmouel/snazy","last_synced_at":"2025-04-06T14:12:42.761Z","repository":{"id":37821435,"uuid":"484389826","full_name":"chmouel/snazy","owner":"chmouel","description":"a snazzy json log viewer (with one z)","archived":false,"fork":false,"pushed_at":"2025-03-17T15:07:15.000Z","size":10278,"stargazers_count":33,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-30T13:08:43.826Z","etag":null,"topics":["cli","knative","kubernetes","logs","rust","tekton","uber-zap"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chmouel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-22T10:21:23.000Z","updated_at":"2025-03-17T15:07:18.000Z","dependencies_parsed_at":"2023-02-16T17:45:34.041Z","dependency_job_id":"2ee9f253-ebae-4228-a2f1-2cbcac53a916","html_url":"https://github.com/chmouel/snazy","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fsnazy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fsnazy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fsnazy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fsnazy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chmouel","download_url":"https://codeload.github.com/chmouel/snazy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247492559,"owners_count":20947545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","knative","kubernetes","logs","rust","tekton","uber-zap"],"created_at":"2024-11-08T21:17:30.811Z","updated_at":"2025-04-06T14:12:42.732Z","avatar_url":"https://github.com/chmouel.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![codecov](https://codecov.io/gh/chmouel/snazy/branch/main/graph/badge.svg?token=71R8DKNQVS)](https://codecov.io/gh/chmouel/snazy) [![Version](https://img.shields.io/crates/v/snazy.svg)](https://crates.io/crates/snazy) [![AUR](https://img.shields.io/aur/version/snazy-bin)](https://aur.archlinux.org/packages/snazy-bin) [![CICD](https://github.com/chmouel/snazy/actions/workflows/rust.yaml/badge.svg)](https://github.com/chmouel/snazy/actions/workflows/rust.yaml) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit\u0026logoColor=white)](https://github.com/pre-commit/pre-commit)\n\n# snazy - a snazzy log viewer\n\nSnazy is a simple tool to parse json or other type of logs and output them in a nice format with\nnice colors.\n\nAs a [`tekton`](http://tekton.dev) and [`pipelines-as-code`](https://pipelinesascode.com/) developer who has to dig into controller/webhook logs all the time I wanted something that is a bit easier to look in the eyes and identify error/info/warning statements easily.\n\nYou do not have to use it only with `tekton` but work well with projects that uses\n[`go-uber/zap`](https://github.com/uber-go/zap) library like\n[`knative`](https://knative.dev) and many others.\n\nIt can work as a super-\"[tail](https://man7.org/linux/man-pages/man1/tail.1.html)\" too if you want to stream logs and being able to have \"actions\" or \"highlights\" on a regexp match.\n\n## Screenshot\n\n![screenshot](./.github/screenshot.png)\n\n## Installation\n\n### [Binaries](https://github.com/chmouel/snazy/releases)\n\nGo to the [release](https://github.com/chmouel/snazy/releases) page and grab\nthe archive or package targeting your platform.\n\n### [Homebrew](https://homebrew.sh)\n\n```shell\nbrew tap chmouel/snazy https://github.com/chmouel/snazy\nbrew install snazy\n```\n\n### [Crates.io](https://crates.io/crates/snazy)\n\n```shell\ncargo install snazy\n```\n\n### [Arch](https://aur.archlinux.org/packages/snazy-bin)\n\nWith your favourite aurhelper for example [yay](https://github.com/Jguer/yay) :\n\n```shell\nyay -S snazy-bin\n```\n\n### [Nix/NixOS](https://nixos.org/)\n\nSnazy is available from [`nixpkgs`](https://github.com/NixOS/nixpkgs).\n\n```shell\nnix-env -iA snazy\nnix run nixpkgs#snazy -- --help # your args are here\n```\n\n### [Bin](https://github.com/marcosnils/bin/)\n\n```shell\nbin install github.com/chmouel/snazy \n```\n\n### [Docker](https://github.com/chmouel/snazy/pkgs/container/snazy)\n\n```shell\nkubectl logs deployment/pod foo|docker run -i ghcr.io/chmouel/snazy\n```\n\n### [Source](https://github.com/chmouel/snazy) install\n\nSnazy is built with rust, if you want to compile it directly you just need to\ngrab the source and run `cargo build`. (assuming you have the rust tool chain [installed](https://rust-lang.github.io/rustup/installation/index.html))\n\n## Usage\n\n- Usually you use `snazy` by \"piping\" logs into it :\n\n```shell\nkubectl logs deployment/controller|snazy\n```\n\n- It supports streaming too. When you have a `kubectl logs -f` it will just wait\n  for input and snazzily print your logs from the stream (one line at a time).\n\n- you can pass one or many files on the command line to `snazy` and it will\n  parse them rather than using the standard input.\n\n- If you do not pass a file and your input comes from\n  \u003chttps://github.com/boz/kail\u003e it will automatically detect it and print the\n  `namespace/pod[container]` as prefix :\n\n![screenshot](./.github/screenshot-kail.png)\n\n- The flag \"--kail-prefix-format\" let you customize how to display the kail\n  format, the templates `{namespace}`, `{pod}`, `{container}` will be replaced\n  by its value and a \"\\n\" will be replaced by a newline. As an example if you\n  want to only show the current pod followed by a newline you can use the\n  following template:\n\n  `--kail-prefix-format \"{pod}\\n\"`\n\n  the environment variable `SNAZY_KAIL_PREFIX_FORMAT` let you make this setting permanent.\n\n- If you do not any prefix for kail you can pass the `--kail-no-prefix` flag.\n\n- If you want to highlight some patterns you can add the option `-r/--regexp`\n  followed by a REGEXP and `snazy` will highlight it. You can have many `-r`\n  switches with many regexps, and you get different highlight for each match.\n\n- If you want to have the highlight forced to some colors you can add the color\n  at the beginning of the regexp followed by a colon. The colors can be one of\n  `yellow`, `red`, `green`, `blue`, `magenta`, `cyan`, `white`, `black` or an RGB\n  color model e.g: `88,48,235`. For example if you want to highlight ERROR in red\n  and WARNING in yellow you can do:\n\n```shell\n% kubectl log pod|snazy -r red:ERROR -r yellow:WARNING -r green:INFO -r 88,48,235:MITIGATED\n```\n\n- You can define a background color as well with this format, Only fixed colors\nare supported for now (ie: no rgb or fixed):\n\n```shell\n% kubectl log pod|snazy -r fg=black,bg=yellow:ERROR\n```\n\n- If `snazy` don't recognize the line as JSON it will simply straight print\n  it. Either way it will still apply regexp highlighting of the `-r` option or\n  do the action commands matching (see below). This let you use it for any logs\n  to do some regexp highlighting and action on pattern.\n\n- If you want to only show some specific levels, you can add the flag\n  `-f`/`--filter-levels` to filter by level or many `-f` for many levels, for\n  example, this only show warning and error from the log:\n\n```shell\n% kubectl log pod|snazy -f warning -f error\n```\n\n- If you pass the flag `-l/--level-symbols` or set the environment variable\n  `SNAZY_LEVEL_SYMBOLS`, snazy will show some pretty emojis rather than plain log\n  level label :\n\n![snazy level symbols](.github/screenshot-level-symbols.png)\n\n- You can customize the time printed with the `--time-format` flag (or the environment\n  variable `SNAZY_TIME_FORMAT`), the variable respect the UNIX\n  [`strftime`](https://man7.org/linux/man-pages/man3/strftime.3.html) format\n  strings.\n\n- You can specify a timezone with the `--timezone` flag (or the environment variable\n  `SNAZY_TIMEZONE`). By default, the timestamps are displayed in the server's timezone\n  (usually UTC). The timezone should be specified in the [IANA timezone database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) format\n  (e.g., `America/New_York`, `Europe/Paris`, `Asia/Tokyo`).\n\n  ```shell\n  kubectl logs deployment/controller | snazy --timezone America/New_York\n  ```\n\n- If you want to skip showing some lines you can specify the flag\n  `-S/--skip-line-regexp`. When it matches the word or regexp in\n  this value it will simply skipping printing the line. You can have multiple flags\n  if you want to skip multiple lines.\n\n- You can do your own field matching with the `-k/--json-keys` flag, you need to pass the fields `msg`, `level` and `ts`.\n  The fields target a key in a json payload specified as [JSON Object notation](https://www.rfc-editor.org/rfc/rfc6901). The description of the fileds are:\n\n  - `msg`: The message text (string)\n  - `level`: The log level (eg: info) (string)\n  - `ts`: The timestamp, a float or a datetime.\n\n  If any of those fields are missing the parser will fails.\n\n  **Example**:\n\n  ```shell\n  echo '{\"the\": {\"msg\": {\"is\": \"message\"}, \"level\": {\"is\": \"INFO\"}, \"ts\": [{\"is\": \"2022-04-25T14:20:32.505637358Z\"}]}}' | \\\n        snazy -k msg=/the/msg/is -k level=/the/level/is -k ts=/the/ts/0/is\n  # =\u003e INFO  14:20:32 message\n  ```\n\n- Snazy support action command on regexp, which mean if you have a regexp\n  matching a message it will run an action on it. It currently supports only one\n  action one regexp. If you specify the string `\"{}\"` it will be expanded to\n  the matched string. For example on MacOS this command will display a\n  notification with the pipelinerun that has succeeded:\n\n  ```shell\n  snazy --action-regexp \"pipelinerun(s)?\\s*.*has success\" --action-command \"osascript -e 'display notification \\\"{}\\\"'\"\n  ```\n\n## Interactive filtering with fzf\n\nYou can go even further with UNIX shell pipelines, and feed snazy to fzf for interactive filtering of the stream. for example to stream everything on a kubernetes cluster with kail, transforming the logs via snazy and finally using fzf to interactively select the patter to match:\n\n```shell\nkail --since=1h | snazy | fzf +s --ansi\n```\n\nThis will give you a prompt with [`fzf`](https://github.com/junegunn/fzf) where you can type the query you want.\n\n## Show GitHub Action Runs logs with snazy\n\nAn handy script located [here](./misc/gh-run-logview-snazy) let you show the log\nof a GitHub action runs through snazy and the\n[`bat`](https://github.com/sharkdp/bat) pager.\n\nYou will need to setup the [gh cli](https://github.com/cli/cli) and install\n[fzf](https://github.com/junegunn/fzf) to make it works.\n\nHere is a video showing the feature \u003chttps://streamable.com/7sf1hq\u003e\n\n## Shell completions\n\nShell completions are available for most shells using the command `--shell-completion` for example `--shell-completion=zsh`. Many different shell are supported. I let the reader figure out how to use them with their respective shells. Brew and RPM packages should have them auto configured for bash/fish/zsh.\n\n## FAQ\n\n- I have seen a tool like that before with another stupid name? I used to have a python script that does the same and more called\n  ([sugarjazy](https://github.com/chmouel/sugarjazy)) but I wanted to experiment with Rust, so I called this one\n  [snazy](https://www.urbandictionary.com/define.php?term=snazy).\n- You missed a z to snazzy. True that. But snazy is easier to google than snazzy :p\n- Why rust? Good question, I guess i'll go by why not? it's kinda nice to program high level cli with low level language easily.\n  [sharkdp/fd](https://github.com/sharkdp/fd)\n\n## Copyright\n\n[Apache-2.0](./LICENSE)\n\n## Authors\n\n### Chmouel Boudjnah\n\n- Fediverse - \u003c[@chmouel@chmouel.com](https://fosstodon.org/@chmouel)\u003e\n- Twitter - \u003c[@chmouel](https://twitter.com/chmouel)\u003e\n-\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchmouel%2Fsnazy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchmouel%2Fsnazy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchmouel%2Fsnazy/lists"}