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
Introduced a custom NATS logger facade #1076
base: main
Are you sure you want to change the base?
Conversation
… logger facade. Added new logs for dns resolving and socketdataport timeout to showcase usage in 2 examples where logging can be valuable.
@@ -0,0 +1,32 @@ | |||
// Copyright 2020 The NATS Authors |
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.
Nit: Update the date to 2024
* nats.java library consumers. | ||
* An exemplary default implementation of this interface logging to STDOUT can be found in this repo. | ||
*/ | ||
public interface INatsLogger { |
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.
Please change to NatsLogger since we don't use I
anywhere else. Just being consistent, right or wrong.
@stefanLeo Ok so this is not bad, but I can't use it this way. I was okay with only providing a way to handle existing trace statements, not add logging.
I see you made some changes to ServerPool and SocketDataPortWithWriteTimeout. The best I can offer is if you need logging in here is you will have to write your own and provide them in Options. The logging in SocketDataPortWithWriteTimeout is actually not meant to be logged. It's actually a workaround for java socket write not having a write timeout like it has a read timeout, i.e. not an error situation, but an error handling situation. |
Added Noop Logger as default logger Added Logger to Options builder Added Log levels verification to StdOutLogger Changed NatsConnection log generation to user LOGGER methods Changed Log Levels for DNS & SocketDataPortWithWriteTimeout to not log to STDOUT per default.
I did incorporate all of your feedback. Thx. I hope I did understand your last point correct... I can change it again if I got it wrong. The lib should now behave exactly as before this PR in the default option and connecttrace option. I left in den DNS and Sockettimeout logs for now, but reduced their log level which means noone will ever see them unless explicitly asked for. If you insist on removing them I will do so. I think providing more logs is better than less and then let the custom logger provided by the lib consumer decide what he/she wants to log or not. Otherwise people are basically blind in production if something happens or have to override and maybe copy code just to get some information about what has happened, which is also dangerous at times... |
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 you want to replace the NATS trace logger per connection, I'm perfectly okay with that.
I would make a trace logger interface, a way to set it in the options and some changes in NatsConnection.
NatsConnection can use an anonymous no-op implementation if one is not supplied in options and isTraceConnection is false. It can use a backward compatible anonymous implementation if one is not supplied but the isTraceConnection is true.
There should be no other logging additions to the PR. If we start adding logging and it touches performance even a millisecond, I'm going to get dinged left and right for slowing the client down.
I need to check with other client devs to see about their clients to even see what logging they provide, if any.
@@ -46,6 +43,7 @@ | |||
|
|||
class NatsConnection implements Connection { | |||
|
|||
private final static NatsLoggerFacade LOGGER = NatsLoggerFacade.getLogger(NatsConnection.class); |
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.
LOGGER cannot be static. It must be specific to the instance of the connection, because the dev may want to log connections differently.
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.
OK will change.
Pls. see https://www.slf4j.org/faq.html#declared_static for why I chose static in the first place. I.e. from a performance (CPU, Heap) PoV and "commonness" static is preferred. If IOC has higher prio it has to be an instance variable.
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 howver you meant someting differnt - you meant that every connection could have its own "logger" implementation that differes from others.. If yes then this has to change maybe on another level as well (in the facade) ... Will provide a change for this.
/** | ||
* Property used to configure a builder from a Properties object. {@value}, see | ||
* {@link Builder#errorListener(ErrorListener) errorListener}. | ||
*/ | ||
public static final String PROP_ERROR_LISTENER = PFX + "callback.error"; | ||
public static final String PROP_LOGGER = PFX + "callback.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.
Does not seem like the correct property name.
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.
:-) woah must have been too late... Fixed.
This is what I was thinking: #1077 |
Made logger instances connection specific where needed Moved log level validation to facade which reduces GC pressure as less objects are created if level is set to OFF within the logger
I did now make the logger connection specific where needed and removed nooplogger again. This can be covered much better by log levels and should also improve performance as less objects are created in case logging is disabled. So i.e., it is closer to NoOpLogger than it was before. Let me know if I have to remove the logs I added - these should not affect performance at all as they are not on the ciritical path. Regarding log and perfomrance in general: I think the world is turning that way as you also do with NATS server adding open telemetry support in 3.11, which I think is an awesome feature. I.e., everyone is adding not only logs but metrics and traces. |
As far as the trace logging I'd prefer to use the PR I built as it is consistent with plugging in something per connection. |
@stefanLeo Copied from #1077 Yes. Fully understood. So the use cases are from my PoV:
|
Rewired all STDOUTS to this facade and added extensive unit tests.
Added new logs for dns resolving and socketdataport timeout to showcase usage in 2 examples where logging can be valuable.
No other NATS code or APIs have been touched - also not the log process provisioning code.
This may then be done upon request as well as making the facades interface more convenient with parameters, log level filtering in the stdoutlogger, etc...
Happy tor receive your feedback and change things as per request.
@scottf FYI and thx again for your time :-)