humanlogio / humanlog

Logs for humans to read.
Apache License 2.0
748 stars 53 forks source link

flatten nested objects #114

Open aybabtme opened 4 weeks ago

aybabtme commented 4 weeks ago

right now, when a nested object is found in the input, it is sprintf("%v"). instead, it should be flattened out with .:

an input of

{"storage": {"from": "2024-10-29T05:47:00Z"}}

currently gets encoded in the kv as:

storage=map[from:2024-10-29T05:47:00Z]

but it should become

storage.from=2024-10-29T05:47:00Z
aybabtme commented 4 weeks ago

Another example:

input:

{"time":"2024-10-29T16:45:54.384776+09:00","level":"DEBUG","source":{"function":"github.com/humanlogio/humanlog/internal/memstorage.(*MemStorageSink).firstMatch","file":"/Users/antoine/code/src/github.com/humanlogio/humanlog/internal/memstorage/memory.go","line":243},"msg":"first match found at index","storage":{"machine.id":5089,"session.id":1730187806608637000,"i":0}}

current render (when fed into humanlog --truncate=false):

Oct 29 16:45:54 |DEBU| first match found at index storage=map[i:0 machine.id:5089 session.id:1.730187806608637e+18] source=map[file:/Users/antoine/code/src/github.com/humanlogio/humanlog/internal/memstorage/memory.go function:github.com/humanlogio/humanlog/internal/memstorage.(*MemStorageSink).firstMatch line:243]

expected render:


Oct 29 16:45:54 |DEBU| first match found at index storage.i=0 storage.machine.id=5089 storage.session.id=1.730187806608637e+18 source.file="/Users/antoine/code/src/github.com/humanlogio/humanlog/internal/memstorage/memory.go" source.function="github.com/humanlogio/humanlog/internal/memstorage.(*MemStorageSink).firstMatch" source.line=243
ferh6t commented 2 weeks ago

Hi @aybabtme,

In my local, I have a small piece of code for this issue. Before I open a PR, I wanted to ask a couple of questions.

1- {"time":"2024-10-29T16:45:54.384776+09:00","level":"DEBUG","source":{"function":"github.com/humanlogio/humanlog/internal/memstorage.(*MemStorageSink).firstMatch","file":"/Users/antoine/code/src/github.com/humanlogio/humanlog/internal/memstorage/memory.go","line":243},"msg":"first match found at index","storage":{"machine.id":5089,"session.id":1730187806608637000},"user":{"role":"admin","access":{"lastLogin":"datetime.datetime.now().isoformat()","permissions":"no-access"}}}

For this Input I have this output.

Screenshot 2024-11-10 at 22 19 28

Does the order of the fields matter? Which logic is implemented when kv is printed out?

2- I implemented it for json logs. Is it necessary to implement for logfmt and their docker compose implementations(I guess they are using the same functions, no need)?

aybabtme commented 2 weeks ago

Hi @ferh6t , this looks great. For logfmt, I'm not sure what nested objects look like in that format. My understanding is that it's a single level key-value format. Do you have an example of nested objects in logfmt?

ferh6t commented 2 weeks ago

Hi again. Yes, I see, there is no need for that. If you add me as a collaborator, I can open a PR for that small part.

aybabtme commented 2 weeks ago

@ferh6t happy to add you as a collaborator later, but there's no need for that to open a PR. the typical workflow in open-source is to fork, push your change to your fork, and then open a PR from your fork to the target repo.