[HN Gopher] Angle-grinder: Slice and dice logs on the command line
___________________________________________________________________
Angle-grinder: Slice and dice logs on the command line
Author : kqr
Score : 118 points
Date : 2024-04-29 07:36 UTC (15 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| liampulles wrote:
| Cool tool!
|
| I think log processing is something that is easy enough to do
| (stream through STDIN lines) and has specific enough requirements
| to individual teams that it's worth building ones own little
| pipe-in binary.
|
| Can start by highlighting common log fields, but later add
| subcommands to aggregate, or analyze known problems, etc.
| surfingdino wrote:
| I see a lot of cool tools in the broadly defined dev space
| written in Rust. Best ad for Rust.
| hnlmorg wrote:
| I'm not taking anything away from, Rust, it is a great language
| for CLI developer tooling. But in fairness you'll find a
| plethora of tooling written in all popular languages these
| days. This is also true for a great deal of "uncool" languages
| too, like Perl.
|
| I also think newer languages benefit from the fact that CLI
| developer tooling is a great "hello world" type project to work
| on. Such projects solve a very real problem that someone
| starting out in that language wants to solve, while also often
| being simple enough problem to learn that language in.
| guappa wrote:
| Language in which something is written tells a lot.
|
| For example for something written in go you might expect
| signals to be mishandled, colour escape codes when piping to
| another command, and non-GNU command line parsing.
|
| It's not inherent to the language, but it's more about the fact
| that often people who write the libraries don't know about unix
| and the system calls they should be using.
| hnlmorg wrote:
| Ironically, neither of your examples requires understanding
| syscalls in low level languages like C either.
|
| In fact I don't think your average developer should need to
| understand syscalls to write applications. That kind of stuff
| should be abstracted away. Plus if you want to write _good_
| applications for Linux /UNIX then that might mean using
| platform specific syscalls rather than sticking with POSIX,
| which would be a maintainability nightmare if it wasn't
| already abstracted. Furthermore, some platforms, like macOS,
| don't even guarantee binary compatibility for syscalls
| between releases. So you're not even supposed to making
| syscalls directly in Darwin.
|
| So with that in mind, application developers are usually
| encouraged to stick with their respective language runtime as
| the OS interface -- and even then, a lot of language runtimes
| still just hook into libc rather than making syscalls
| directly themselves.
|
| To come to your examples specifically, even in C you wouldn't
| directly call ioctl on your fd to check if it's a TTY.
| Instead you'd use isatty() in libc. (In case anyone doesn't
| follow, this is to check if stdout is being piped or a tty,
| and thus whether to output or suppress human readable
| formatting like ANSI escape sequences).
|
| Your point about GNU argument passing is also off. GNU is a
| convention and it's only officially supported in GNU/Linux.
| You talk about understanding UNIX while referencing
| conventions that aren't even anything to do with UNIX!
|
| Lastly, I'm not sure why you singled out Go when there are a
| lot of advanced developer tools written in it, from pretty
| much everything by Hashicorp (Terraform, Vault, Consul, etc)
| through to Docker and Kubenetes. I don't want to start a
| flame war about Go nor its developers, just saying it was yet
| another weird example in a comment already full of weird
| examples.
| kosolam wrote:
| Nice! I shall give it a try. Looks like a very developer oriented
| tool.
| asicsp wrote:
| Previous discussion:
| https://news.ycombinator.com/item?id=27877956 _(144 points | July
| 19, 2021 | 21 comments)_
|
| See also: https://github.com/Textualize/toolong (terminal
| application to view, tail, merge, and search log files)
| eMPee584 wrote:
| another nice one: lnav (log navigator)..
| ezekiel68 wrote:
| Not sure why "MUSL-compatible" is the default for the binary
| install. This is surely in the minority of Linux distros, even in
| 2024. I imagine it's best (when distributing) to target the
| convenience of the end-user rather than of the dev team (since
| one could simply create a separate CICD channel that builds with
| a glibc-based starting image).
|
| Makes me wonder if the 'cargo install' method requires MUSL libc.
| This is not stated but that also makes it unclear since it comes
| right after the former variant.
| superamadeus wrote:
| Most likely for Docker/container users using Alpine Linux or
| similar.
| blueflow wrote:
| It does not matter as the libc part is statically linked into
| the binary. This means that this project runs on any linux
| kernel that the musl libc supports, regardless of which libc
| the rest of the system uses.
|
| Musl was likely picked because glibc doesn't support proper
| static linking.
| piterrro wrote:
| For those who find this tool interesting, I can recommend to take
| a look at Logdy.dev (https://logdy.dev)
| https://github.com/logdyhq/logdy-core Similar use case, different
| implementation. Disclaimer, I'm author of that tool.
| phreeza wrote:
| Is the name a riff on a similar google-internal tool?
| alexhutcheson wrote:
| For those not familiar, Google had a tradition of choosing
| names of wood-processing tools for "logs" analysis:
|
| - Sawzall: https://research.google/pubs/interpreting-the-data-
| parallel-...
|
| - Dremel: https://research.google/pubs/dremel-interactive-
| analysis-of-...
|
| - PowerDrill: https://research.google/pubs/processing-a-
| trillion-cells-per...
| aidos wrote:
| Before anyone gets any ideas, I'm sure _it is_ possible, but
| angle grinders are most definitely not designed for cutting
| wood. They're dangerous enough as it is when you're using
| them correctly!
| jcgrillo wrote:
| here you go: https://i.pinimg.com/originals/5f/45/2d/5f452d
| c99acc8307ab3a...
| chrisweekly wrote:
| See https://lnav.org for a powerful mini-ETL CLI power tool; it
| embeds SQLite, supports ~every format, has great UX and easily
| handles a few million rows at a time.
| dloss wrote:
| Angle-grinder is really nice and the successor of sumoshell (by
| the same author).
|
| I maintain a list of tools like these as part of the docs for my
| own tool klp (https://github.com/dloss/klp), which I think has a
| few useful features that are not in angle-grinder, but is orders
| of magnitude slower, because it's implemented in pure Python
| instead of Rust.
| culopatin wrote:
| Chainsaw would be a more fitting name. I don't think angle
| grinders are used to slice logs. Perhaps a bandsaw.
| jonstewart wrote:
| There's already a DFIR log tool named chainsaw:
| https://github.com/WithSecureLabs/chainsaw
| cduzz wrote:
| Not to be juvenile, but I firmly believe that "computer log
| processing" is much more comparable to sewage treatment than
| converting trees into lumber.
|
| Maybe you can't get funding from people who name things after
| middle earth magic rocks if you call your system "sludge
| strainer" ?
| stcredzero wrote:
| _Not to be juvenile, but I firmly believe that "computer log
| processing" is much more comparable to sewage treatment than
| converting trees into lumber._
|
| I now have another facet to add to my appreciation of "Log"
| from the Renn & Stimpy show.
| 082349872349872 wrote:
| "Sawmill"? https://en.wikipedia.org/wiki/Sawmill (or maybe
| "crosscut"?)
| alexhutcheson wrote:
| Angle grinders are useful when working with pipes, though.
| eichin wrote:
| Slice, no. But look up "wood carving disc" or "wood shaping
| disc" for some angle-grinder related crimes against woodworking
| - lots of power, but you'd better know exactly what you're
| trying to accomplish. (Besides, after 3+ decades of command-
| line-enhanced log processing, you can _assume_ that a fitting
| or obvious name has been used three or four times already :-)
| derefr wrote:
| For anyone who read the README and is now thinking that agrind is
| "like jq but with aggregations" -- it's much more than that, and
| (at least in the tasks I use it for) really more _complementary_
| to pipeline transformer tools like jq.
|
| Specifically, the "killer app" feature for agrind, is that it's a
| _live reporting_ tool. You _can_ just throw a CSV file through
| agrind to get a nice one-shot aggregation out. But if you stream
| a live data source into it -- think something like "your k8s
| ingress controller's access logs" -- then agrind will grab your
| TTY; draw a table to fills it; and begin _live-updating_ that
| table with the report, with the rows re-ordering to stay sorted
| as more data is received.
|
| Want to see e.g. the top 10 highest-duration HTTP requests by
| path given some particular HTTP status code? You can just start
| streaming logs into it, and the report will gradually come into
| focus as it finds matching events. Hit ^C when the data has
| "stabilized" (i.e. when datapoint ranks are no longer jumping
| around), and you'll be left with the last-refreshed state of the
| table in your terminal scrollback, to use in further
| investigations.
|
| agrind _has_ jq-like manipulation tools, but honestly, I mostly
| still use jq for that part. I have no idea how to unwrap JSON
| list items in agrind (or if that 's even possible), but if I want
| to do that, I'll just: http
| localhost:8001/v1/debug/inflight-requests | jq -c
| '.[].jsonPayload' | agrind '* | json | sum(dur) by path'
|
| ---
|
| Bonus recommendation, as it's something I use together with jq
| and agrind: stern (https://github.com/rancher/stern) -- for live
| tail(1)ing of the O(N) pods of a k8s Deployment, right from the
| cluster, without any external log multiplexer.
| stern ingress-nginx-controller -i some_path_frag -o raw
| 2>/dev/null | agrind '* | json | where status == 403 | count by
| client_addr' 2>/dev/null
|
| Note the two instances of `2>/dev/null` here.
|
| The first one is to remove the "connected to pod XYZ" meta info
| from stern(1) output, that would muck up the agrind table.
|
| The second one, though, is more interesting: it's there because
| unlike jq, agrind _doesn 't die_ when it hits an unparseable
| line! Instead, it just spits a parse error and continues. So you
| can have agrind consume a "dirty" data stream -- e.g. a combined
| "structured JSON access log + plaintext error log" stream -- and
| then just discard stderr, to silence the resulting errors printed
| from the failed attempts at parsing the error-log lines of the
| stream.
| cryptonector wrote:
| I mean, jq can aggregate... Maybe it should have more
| interesting aggregations built-in though.
___________________________________________________________________
(page generated 2024-04-29 23:01 UTC)