Comments (9)
Reading through #110 I can see that this may be solved with a more robust implementation of LogHandler
elsewhere, that has an ordered dictionary backing the metadata.
from swift-log.
The storage is dictionary (as well as conceptually, it's a "bag of key/values"), I don't think anyone should depend on order of things in those bags, esp as they may be passed around and revived from other contexts and thus preserving order I don't think is trivial (nor something we should strive for) for metadata.
So: Yes, I'd say this is on purpose and should not change.
from swift-log.
@ktoso Everything you say is right. However it's quite weird that if you do
log.info("hello", metadata: ["a": "b", "c": "d"])
log.info("hello", metadata: ["a": "b", "c": "d"])
you may get
a=b c=d hello
c=d a=b hello
it can be quite frustrating to read. That we're using a dictionary is really just an implementation detail. So of course, we not change it and use it as an incentive to have people write their own LogHandlers but we could also argue that this should serve as an example. And in the real world, I think it's fair to expect that the order is stable. We could just sort them for example? WDYT?
from swift-log.
I think there is no problem to let logging backends decide the final output format.
If they want to display the metadata in order, no matter by key, by value, ascending or descending, they can sort it in their way.
In this case StreamLogHandler
, we can simply change the following implementation
private func prettify(_ metadata: Logger.Metadata) -> String? {
return !metadata.isEmpty ? metadata.map { "\($0)=\($1)" }.joined(separator: " ") : nil
}
to something like
private func prettify(_ metadata: Logger.Metadata) -> String? {
return !metadata.isEmpty ? metadata.sorted(by: <).map { "\($0)=\($1)" }.joined(separator: " ") : nil
}
to achieve the requirement.
I think this modification is useful and I'll be happy with it, but maybe we should consider how far should StreamLogHandler
go?
I guess there might someone says: "Why the key/value pairs not separated by a common?" or "Why not wrap the metadata in a pair of [] to distinguish from the message body?" and so on. Should this package complete all these requests? or leave StreamLogHandler
a simple but just working sample implementation?
from swift-log.
a=b c=d hello c=d a=b hello
it can be quite frustrating to read.
@weissi Absolutely, that's enough to drive one mad! 😉
And as someone who looks at logs a lot I've also hit this frustration a long time ago as well, but I don't believe changing the storage is the solution. It is up to the backend how to print (that's what they do!) and not for the storage to decide -- as @ShivaHuang also points out very well above.
Since I look at logs a lot in my work, that's also exactly what I do in a LogHandler I have:
for key in metadata.keys.sorted() ...
It's up to formatters to do that.
It's unfortunate with the existence of StreamLogHandler
inside of this "API only (but not really)" package, since we hit the
[...] maybe we should consider how far should StreamLogHandler go?
I guess there might someone says: "Why the key/value pairs not separated by a common?" or "Why not wrap the metadata in a pair of [] to distinguish from the message body?" and so on. Should this package complete all these requests? or leave StreamLogHandler a simple but just working sample implementation?
trouble again...
At some point we really should "split off" work on a good log handler into a separate project and do all the right things there.
Is that time now perhaps?
from swift-log.
(Additional thought even answering this "what does order mean" here may have different interpretations: you said "I wrote a,b
so I expect a,b
but that means "keep order" while often you might actually want "alphabetically" rather than "keep order" if metadata is set in various places etc... So even this already has some nuances heh).
from swift-log.
[...] maybe we should consider how far should StreamLogHandler go?
I guess there might someone says: "Why the key/value pairs not separated by a common?" or "Why not wrap the metadata in a pair of [] to distinguish from the message body?" and so on. Should this package complete all these requests? or leave StreamLogHandler a simple but just working sample implementation?trouble again...
At some point we really should "split off" work on a good log handler into a separate project and do all the right things there.
I don't think the provided log handler has to be amazing or even great, but the lack of consistent ordering can be very frustrating as has been pointed out! I don't think a separate great handler would even be the right solution here, it's the low barrier to entry of this handler that's useful: I often hit this issue when I'm developing or debugging when it's more frustrating to pull in another dependency.
FWIW I don't think it really matters how they're ordered, as long as it's consistent.
from swift-log.
I guess we all agree random order sucks (I don't deny that, it's completely unusable to me as well, but I use custom handlers so I live with it fine); You are right though, many people will run with the default... And maybe we then have to analyze those logs, and it'd be nice to not lose sanity... 🤔
So, maybe just sorted by keys as a "stable predictable" way to print them? Would you want to send in a PR @glbrntt?
from swift-log.
Fixed in #151, could land as soon as 1.4.1, we'll see when we cut that.
from swift-log.
Related Issues (20)
- xcodebuild DocC error with Xcode 14 HOT 24
- Update SwiftFormat version HOT 1
- Provide Test Helpers Publicly HOT 6
- Toggle verbose or off HOT 1
- Crash when using error log / Incomplete LogHandler implementation HOT 2
- Infinite recursion between deprecated API's HOT 4
- MultiplexLogHandler to learn about metadata providers
- Add new Discord Logger to README HOT 2
- Make `StdioOutputStream` public HOT 1
- Supported way of accumulating metadata down the callstack HOT 9
- Logging function autoclosures aren't "rethrows" HOT 8
- Simplify logging `Error` types HOT 4
- Support advanced loghandler metadata use cases HOT 2
- Make StreamLogHandler initializers public
- How should I disclose using Swift Log in my iOS app?
- Unsupported runtime for visionOS HOT 1
- Fails to compile on Fedora 39 with Swift 5.8.1 (From repos) or official 5.9 binaries HOT 7
- PrivacyInfo Manifest HOT 2
- visionOS Compatibility HOT 1
- "Unsupported Runtime" when compiling for xrOS HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swift-log.