Comments (7)
For Flogger we have settled on not supporting multiple loggers in a class (since we just couldn't find a valid use case). However I'm always interested in understanding more about how other people think of loggers, so I'd be interested in knowing what value having multiple loggers in a class has for you.
When JDK loggers are given different names, it doesn't affect what's logged (since that's always the class/method from where the log statement was called, regardless of the logger name). The logger name only affects how logging is configured (which handlers, filters and log level are set).
Now since the log level control will often be done by people running the code (not people who wrote the code) it's important that the logger name is something people can "guess" from the log output. This is why Flogger is limited to only having loggers for an enclosing class, so the log-site information tells someone who wants to configure logging what the name of the logger is.
For example if you see:
""INFO [com.foo.bar.MyClass:myMethod:123] This is a spammy log message you want to turn off.""
then you can know that the logger called "com.foo.bar.MyClass" is the one you need to configure.
Similarly, if you see interesting class names in stack traces, you know which loggers to make for verbose.
Now, other log systems (e.g. log4j) might have a different interpretation of what a logger name "means", but since Flogger is intended to work with any reasonable backend, it's not feasible to use the semantics of any one logging system in the frontend API. That's why we settled on "the logger name is the name of the class that's using it" for simplicity and maximum interoperability.
from flogger.
Code below - the use case: tracking memory allocation for each web request in a filter. The results of that go to two spots:
- A class-logger as a warning (with url context etc) when over certain thresholds (code below)
- A "memory" logger that is configured (on the back-end) to write to a separate, structured log file that can later be analyzed ("find me the p99 memory allocation for operation X", "which operation has the highest p99 memory allocation", etc). This log file has no requirement for call-site information.
(logger is SLF4J which has placeholder replacements but no formatting replacements, hence the String.format)
Another one that comes to mind is logging all SQL statements in a structured log file (SQL, elapsed time & other context). The common factor seems to be having a separate, structured log file (e.g. tab separated) w/o call-site information.
private final Logger logger = LoggerFactory.getLogger( getClass() );
private final Logger memoryLogger = LoggerFactory.getLogger( "memory" );
String msg = String.format("%s %s %5.3f %d %d", request.getServerName(), request.getRequestURI(), elapsedTimeSeconds, allocatedMemory, allocationRate );
memoryLogger.info( msg );
if ( allocationRate > allocationRateWarningLevel * MB_TO_BYTE ) {
logger.warn( String.format("Action exceeded memory allocations of %d MB/sec with a value of %.1f MB/s", allocationRateWarningLevel, (double)allocationRate / MB_TO_BYTE ) );
}
if ( allocatedMemory > allocationTotalWarningLevel * MB_TO_BYTE ) {
logger.warn( String.format( "Action exceeded %d MB total memory allocation with a total allocation of %.1f MB", allocationTotalWarningLevel, (double)allocatedMemory / MB_TO_BYTE ) );
}
from flogger.
Flogger is only intended for debug logging (optional logging that can help during development). If you need other things logged all the time (as part of a program's correct execution) then I'd recommend a different logging API (one without "log levels" or "rate limiting" etc.).
For sending different debug logs to different output, you could have a backend handler that does the splitting based on metadata attached to the log statement (we do similar things inside Google).
from flogger.
@cslee00 IMO for logging details such as in your use case, annotation and method interceptor based on the AOP paradigm seems a better candidate.
I encountered a similar situation, where the metrics of the api/service level method calls were to be logged. Designing an independent route to log such generic information made more sense to me, as this way it can be reused much easily.
from flogger.
I don't see compelling evidence for modifying Flogger for this use case (it seem distinct from "debug logging").
from flogger.
@cslee00 What about this workaround?
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static class Memory {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
}
... now use `logger` and `Memory.logger`
from flogger.
That's an interesting approach, thanks for sharing. Looks like it would work.
Ultimately I went along the lines of what @hagbard suggested, treating my structured logging needs separately. While there's some overlap with what logging back-ends provide, and some upfront work to get it in place, it's ultimately cleaner to have focused event-handling code (which is really what it is, not logging code).
from flogger.
Related Issues (20)
- How do you import the project into intellij? HOT 4
- Guice/ErrorInjectingConstructor from unit test HOT 7
- Benchmarks and String Creation HOT 19
- Architecture diagram for flogger
- Extensibility How to HOT 9
- Better document Flogger's status (active, maintained, in use at Google) HOT 5
- Support for java.util.ResourceBundle HOT 9
- Add tags from thread context to log HOT 17
- Use java.time.Duration for atMostEvery in LoggingApi. HOT 2
- Flag --incompatible_disable_starlark_host_transitions will break Flogger in Bazel 7.0 HOT 6
- Release schedule?
- Default JavaDocs generated for Flogger confusingly suggest it's deprecated (it isn't). HOT 2
- How to handle ScopedLoggingContext for new Threads / ThreadPools? HOT 1
- Provide a log writer to produce JSON log items according to Elastic Common Schema HOT 8
- I don't believe ScopedLoggingContexts should obviously accept null "no-op" arguments. HOT 5
- Incorrect caller details logged with Flogger in spring boot HOT 2
- Error: 'JavaInfo' value has no field or method 'transitive_deps' HOT 5
- Error: 'JavaInfo' value has no field or method 'transitive_deps' HOT 5
- Next release HOT 2
- ThreadlocalRandom instead of ThreadLocal HOT 8
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 flogger.