-
-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace Log with stdlib logger #133
Conversation
Upon further reading, should I change the loggers to all print to a single fd to also fix #121? |
corral/util/log.pony
Outdated
.> append(level.string()) | ||
.> append(": ") | ||
.> append(msg) | ||
primitive LevelLogFormatter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this used? I'm wondering how valuable it is at the point.
corral/util/log.pony
Outdated
|
||
interface val LogFormatter | ||
fun apply(level: LogLevel, msg: String, loc: SourceLoc): String | ||
use "logger" | ||
|
||
primitive CodeLogFormatter is LogFormatter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this used? I'm wondering how valuable it is at the point.
corral/util/log.pony
Outdated
|
||
primitive CodeLogFormatter is LogFormatter | ||
fun apply(level: LogLevel, msg: String, loc: SourceLoc): String => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the log level where was so it would be polymorphic. Did you see that there's no need for being able to switch between these formatters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log level was there because log.pony had its own implementation of LogFormatter
which accepted a log level argument. The log level argument was used in LevelLogFormatter
to prepend the log message type to the message being logged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup that makes sense now. I like how you moved the log level to being purely at the top level.
Some package level comments for the logging subsystem for corral that details how the different parts work together should be added the PR so that folks in the future won't be asking the same questions.
corral/util/log.pony
Outdated
|
||
primitive SimpleLogFormatter is LogFormatter | ||
fun apply(level: LogLevel, msg: String, loc: SourceLoc): String => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the log level where was so it would be polymorphic. Did you see that there's no need for being able to switch between these formatters?
corral/util/log.pony
Outdated
.> append(": ") | ||
.> append(msg) | ||
primitive LevelLogFormatter | ||
fun apply(level: LogLevel): LogFormatter => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems odd. it only takes a log level?
How is this being used? The lambda concerns me. I'm not sure why that is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand the original code properly, the previous LevelLogFormatter prepended the log type (fine, info, warn, error) to the message being logged. It is only used in main.pony, either as a one-off before exiting or after parsing the command line arguments.
If you like, I could get rid of it by changing the call sites to add the log message type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah so the existing pony standard library logger doesn't have the log level. That makes sense. So, this wraps every log call later and appends the level. That makes sense.
Can you add some doc comments to both the apply method and the primitive to make clear what it is doing?
corral/util/error.pony
Outdated
@@ -1,4 +0,0 @@ | |||
class val Error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was this not used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed it because it clashed with logger.Error, and it only ever held strings to be passed to a logger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.
No. That's more of a "let's look into the interleaving and make sure its not a bug". |
corral/bundle/bundle.pony
Outdated
dir = dir' | ||
log = log' | ||
info = InfoData(JsonObject) | ||
log.info("Created bundle in " + dir.path) | ||
log(Info) and log.log("Created bundle in " + dir.path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here's a question, should there be a "Log" class for corral that keeps the previous form of different methods and it contains the Logger actor and the check to see whether to send a message? It's certainly cleaner and hides to log(Info)
.
By hiding that, we could have single comments per method on the Logger class that explains why that is done to short circuit sending a message to the actor.
It might make the code base more approachable for folks who don't really know Pony.
Thoughts?
I'm not sure how that would come together with the other changes. Perhaps it might be problematic. I'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into that approach, but when I read the docs for the logger package and noticed the use of boolean short-circuiting to avoid the work of building strings, I didn't see a clear way to preserve the encapsulation provided by Log and to get the near zero-cost logging offered by the logger API. That's why I chose to replace all the call sites with the idiomatic use of logger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's amusing that you are reminding me of this given that I wrote those docs for the logger package after writing the logger package.
😆
This looks good aside from needing some documentation for the corral logging package and a couple of the "trickier" formatter usages. |
@rkallos this will need to be rebased as it now has conflicts with changes in cmd_update.pony |
8393e2a
to
23800fd
Compare
Rebased 😃 |
Looks like you have compilation errors after the rebase. |
Note to self: Run tests locally after rebasing. |
23800fd
to
c99ef75
Compare
@rkallos ping me after you've had time to add the documentation/comments and I'll have another look. I might be delayed as I'm moving next weekend and most of my time is going towards work and the move at the moment. |
corral/util/log.pony
Outdated
.> append(msg) | ||
primitive LevelLogFormatter | ||
""" | ||
LevelLogFormatter produces LogFormatters that prepend a log level to entries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't really feel like explains the purpose.
We want to have the log level in all the output for filtering, searching etc that folks might want to do with an unstructured log.
Rather than adding the format to each string at all call locations, we create one of these in main that in turn wraps the other formatters appending the log-level"
That's more than the comment for this primitive, but part of that should be included in this primitive.
I'd like to see log.pony moved from corral/util to corral/log or corral/logging and have a package level doc as well that explains the relationship between this logger and the others and how logging is in general used in corral (as detailed above).
Including the discussion about the short circuit that your commit switched to.
Basically cover everything that I felt the need to ask you about as part oft this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the clarification. I've added some more clarification. Let me know what you think.
corral/log/log.pony
Outdated
work of building strings that won't get logged. This can make log statements | ||
somewhat verbose: | ||
|
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you pony codefence type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. It's pony
, not ponylang
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct
627590c
to
c5545fd
Compare
corral/log/log.pony
Outdated
LevelLogFormatter is used by the logger(s) created in Main. | ||
""" | ||
fun apply(level: LogLevel): LogFormatter => | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines 33 to 35 should be most of the apply method comment.
Creates lambda to... blah blah blah.
corral/log/log.pony
Outdated
sites by creating a special-purpose LogFormatter whose sole purpose is to | ||
prepend the log level. | ||
|
||
LevelLogFormatter is used by the logger(s) created in Main. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
information from 33 to 37 should be in the package level comments.
corral/log/log.pony
Outdated
@@ -0,0 +1,64 @@ | |||
""" | |||
# Logging in corral | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the most important thing for the package docs is to detail the various components and how they interact so...
uses Pony standard logging.
There's a log level formatter that acts as a wrapper around others so that we get INFO etc output without having to spread throughout the codebase.
And here is how it is used with other formatters.
I left some more docs comments. I think what is really missing is, particularly at the package level is... Written for someone who is coming in to modify logging, add new functionality. Description of how logging is done and works. How formatters interact with one another. What each formatter does. Basically what you need to be aware of to make changes. I hope that makes sense. Not sure if it does. |
I had to run an errand... that lead to a thought. For the documentation, there are two audiences. People who want to enhance/change the logging that exists. The basic informational needs of both groups should be met. |
Upon further reflection, I think my approach with let logger = StringLogger(Info, env.err, LevelLogFormatter(Info))
logger(Error) and logger.log("some error message")
// logs "INFO: some error message" To fix this, I think I will introduce a new primitive that accepts a log level and a string and does the prepending there. The resulting code should look like this: let logger = StringLogger(Info, env.err)
logger(Error) and logger.log(LogMsg(Error, "some error message"))
// logs "ERRR: some error message" This avoids the downside of having Alternately, this might make a compelling argument for adding a |
@rkallos This is a good real world use case for the standard library logger. I think it might have highlighted a need for the inclusion of Log Level in the LogFormatter stdlib interface. Would you be up to opening an RFC to make that change? It's small but we need to run it by people. I'm fully in support of it. This PR could then be updated so that it would be a small change to finish off and merge once the standard library has been updated. |
c5545fd
to
a77f4d9
Compare
a77f4d9
to
fb97117
Compare
Now that 0.36.0 is out, work on this can continue. It'd probably be best if I started over, as a lot of the details are now lost to me. |
Closes #127