google / flogger Goto Github PK
View Code? Open in Web Editor NEWA Fluent Logging API for Java
License: Apache License 2.0
A Fluent Logging API for Java
License: Apache License 2.0
...so that flogger can be used by, well, everybody outside Google.
If flogger is already published to another public Maven repository, then please add some documentation on how to consume it.
Adding the Log4J backend causes an internal Gradle exception:
<ij_msg_gr>Project resolve errors<ij_msg_gr><ij_nav>A:\Tobi\Workspaces\JamesBot\build.gradle<ij_nav><i><b>root project 'james': Unable to resolve additional project configuration.</b><eol>Details: org.gradle.api.artifacts.ResolveException: Could not resolve all dependencies for configuration ':runtimeClasspath'.<eol>Caused by: org.gradle.internal.resolve.ArtifactNotFoundException: Could not find jmxtools.jar (com.sun.jdmk:jmxtools:1.2.1).<eol>Searched in the following locations:<eol> https://jcenter.bintray.com/com/sun/jdmk/jmxtools/1.2.1/jmxtools-1.2.1.jar</i>
CONFIGURE SUCCESSFUL in 0s
The faulty dependencies:
compileOnly 'com.google.flogger:flogger:0.4'
runtimeOnly 'com.google.flogger:flogger-log4j-backend:0.4'
Docs page https://google.github.io/flogger/best_practice is displayed weirdly, possibly because of either incorrect interpretation of the markdown markup or incorrect markup itself.
Hi, I tried to integrate flogger into a Liferay OSGi module but I get an error at deploy time:
Unresolved requirement: Import-Package: com.google.common.flogger.backend.android
I see a reference to this package (using Github search) here:
https://github.com/google/flogger/blob/master/api/proguard.cfg
here:
https://github.com/google/flogger/blob/master/api/src/main/java/com/google/common/flogger/backend/Platform.java
and here:
https://github.com/google/flogger/blob/1e2caa0b5b46b79377c5778be42b63f2ebc0655c/api/platformprovider/main/java/com/google/common/flogger/backend/PlatformProviderGenerator.java
but it doesn't seem to exist
https://github.com/google/flogger/tree/master/api/src/test/java/com/google/common/flogger/backend
Should it work without it?
Dear Team,
Please take a look at Bobbin logger: https://github.com/INFINITE-TECHNOLOGY/BOBBIN
Can you consider to adapt it as one of supported Flogger backends?
It features high performance and effective configuration.
Currently there are no known issues in Bobbin, it is a stable release.
If needed we can do appropriate changes (if any) in Bobbin.
Philosophically our vision is very close to that of Flogger, e.g. passing Objects to logger rather than Strings, etc.
Thank you.
For awareness, working on Error Prone refactoring to migrate from other logging APIs:
From the existing documentation it is not clear to me if flogger
is intended mostly as a replacement for the logging api (slf4j
) or also for the logging backend (logback
/log4j
), or both.
The documentation focuses quite convincingly on why this is a better API, but does not seem to give any information about how to configure the backend (log appenders, formatting, MDC etc.). It also doesn't mention anything about whether it's recommended to use an alternate backend, and if so, how it would be accomplished.
Perhaps I've missed something, but could you possibly either point me to the existing docs i missed, or clarify some of the above? Thanks much!
I've written a simple JMH test that test log4j, logback, java.util.logging ang flogger (with the system backend).
When the logging is disable, Flogger is faster than log4j and logback but slower than java.util.logging.
Did i have done something wrong ?
Either best_practice.md should be internal to Google only, or it should be setup in a way so g3docs reads it as GoogleLogger but exporting to github only shows FluentLogger.
It looks like PlatformProvider may be the mechanism for this, though it could be argued it's responsibility is deciding between Android or 'Default' platforms.
Adding a JAR with a custom PlatformProvider does not work (in all cases) as PlatformProvider is included in the base flogger JAR (it may work if at the right spot in the classpath - quirky, not to be relied on).
In contrast to Slf4j it's harder to configure Log4j as a backend for Flogger.
For Slf4j just log4j-slf4j-impl
jar should be in class path, but for Flogger both flogger-system-backend
and flogger-log4j-backend
should be on class path and additionally flogger.backend_factory
property should be set.
Need to include flogger-system-backend
appears illogical if user wants to use Log4j backend and setting system property requires additional work comparing to just having log4j-slf4j-impl
in class path.
It would be nice if flogger can support combining multiple log statements to a single statement which can be emitted manually or automatically. A similar project is https://github.com/paul-wolf/logtrace
The LogSite class and related class are missing from the jar on Maven Central. This result in the following exception during runtime:
java.lang.ExceptionInInitializerError
at com.google.common.flogger.backend.Platform.getCallerFinder(Platform.java:142)
at com.google.common.flogger.FluentLogger.forEnclosingClass(FluentLogger.java:70)
at mypkg.MyClass.<clinit>(MyClass.java:17)
// SNIP
Caused by: java.lang.IllegalStateException: No logging platforms found:
com.google.common.flogger.backend.system.DefaultPlatform: java.lang.NoClassDefFoundError: com/google/common/flogger/LogSite
at com.google.common.flogger.backend.Platform$LazyHolder.loadFirstAvailablePlatform(Platform.java:99)
at com.google.common.flogger.backend.Platform$LazyHolder.<clinit>(Platform.java:67)
... 107 more
I don't know much about Bazel but I guess it has something to do with the new log_site target in api/BUILD. From the perspective of a Maven user the 0.3 release looks broken.
The maven artifacts all use the same java package (com.google.common.flogger
) but are separate jars, which is a problem in Java 9 with the Module system enabled (JPMS).
This notification from IntelliJ leads me to think the LoggingApi
methods themselves should be annotated with @CheckReturnValue
instead of the LoggingApi
class. But I would think IntelliJ/Android Studio should be smart enough to know a void
method has no return value and that it should not warn in that case.
Bazel being less ubiquitous than Maven and Gradle, it'd be nice if there were some build instructions in the CONTRIBUTING.md page
Using DefaultPlatform
one can configure BackendFactory
, LoggingContext
, and Clock
via system properties, however LogCallerFinder
remains set as StackBasedCallerFinder
with no option to change that. I would like the ability added to configure the LogCallerFinder as well. This is certainly useful when one is writing custom backends, especially when it comes to those where naming your loggers using the stack doesn't make much sense. The property name could be flogger.caller_finder
or something of the sort.
Also it would be nice to set the resolveAttribute
method in DefaultPlatform
to public
as the functionality of dynamic configuration and extensibility via system properties seems quite useful and I find that I would like to utilize it for consistency and simplicity when writing dynamically extensible Flogger backends. An example of a useful case for this is where the library you are writing the backend for does not support disabling Levels and you want to make that functionality available through dynamically configured extensions instead of providing a single prescribed way.
I am currently resorting to some less than preferable reflection tricks when doing all of the above in my Fluentd backend as seen here:
https://github.com/agsimeonov/flogger-fluentd-backend/blob/master/src/main/java/com/agsimeonov/flogger/backend/fluentd/FluentdBackendFactory.java
The only other option I see is writing my own Platform
but then I would have to resort to classpath tricks to provide it through a custom PlatformProvider
which also doesn't seem like a particularly pleasant option. I would also have to rewrite a lot of perfectly good code already present in DefaultPlatform
simply to add a tiny bit of extensibility.
Last but not least, and maybe I need to create a separate issue for this as it is not related to the above, I would like to talk about Metadata
and SimpleMessageFormatter
. The code here https://github.com/google/flogger/blob/master/api/src/main/java/com/google/common/flogger/backend/SimpleMessageFormatter.java#L85 appends what is deemed unknown metadata to the log message and there is no way of doing anything fancier with this unknown metadata instead. I propose creating a handler for it that could be used to extend what can be done with it. This is now becoming especially useful when we consider that the with()
functionality GoogleLogger
provided is now merged into FluentLogger
. More people are certainly starting to use Metadata so there needs to be a better way to handle the formatting of this Metadata. Now I know one can simply create their own MessageBuilder
however SimpleMessageFormatter does a lot of things great and one might want to expand upon it rather than completely rewrite it.
If all of or at least a part of all of this seems reasonable I can certainly contribute with a pull request. Let me know what you guys think. I love what you have done with Flogger and I am certainly open to other ideas/suggestions as well. Keep it up!
Is there an idiomatic pattern for migrating to Flogger when using multiple loggers in a class?
Example:
private final Logger logger = LoggerFactory.getLogger( getClass() );
private final Logger someOtherLogger = LoggerFactory.getLogger( "someOtherLoggerName" );
A variation on that would be how to use non-class-named Flogger loggers, as the only out-of-the-box mechanism is based on the class (from FluentLogger):
public static FluentLogger forEnclosingClass() {
// NOTE: It is _vital_ that the call to "caller finder" is made directly inside the static
// factory method. See getCallerFinder() for more information.
String loggingClass = Platform.getCallerFinder().findLoggingClass(FluentLogger.class);
return new FluentLogger(Platform.getBackend(loggingClass));
}
It looks like the com.google.common.flogger.LogSites
class is missing from https://mvnrepository.com/artifact/com.google.flogger/flogger/0.4. I expected the class to be present because the last section of https://google.github.io/flogger/best_practice.html shows that the logSite()
method is part of the API.
I'm not sure if this issue is related to #40.
Using these dependencies:
<dependency>
<groupId>com.google.flogger</groupId>
<artifactId>flogger</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>com.google.flogger</groupId>
<artifactId>flogger-slf4j-backend</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.2</version>
</dependency>
should be enough if I understand https://github.com/google/flogger#how-to-use-flogger correctly.
But this test:
public class FloggerTest {
private static final FluentLogger log = FluentLogger.forEnclosingClass();
@Test
public void test() {
log.atWarning().log("Test: %s", "message");
}
}
fails with:
java.lang.ExceptionInInitializerError
at com.google.common.flogger.backend.Platform.getCallerFinder(Platform.java:142)
at com.google.common.flogger.FluentLogger.forEnclosingClass(FluentLogger.java:70)
at test.FloggerTest.<clinit>(FloggerTest.java:10)
Caused by: java.lang.IllegalStateException: No logging platforms found:
com.google.common.flogger.backend.system.DefaultPlatform: java.lang.ClassNotFoundException: com.google.common.flogger.backend.system.DefaultPlatform
at com.google.common.flogger.backend.Platform$LazyHolder.loadFirstAvailablePlatform(Platform.java:99)
at com.google.common.flogger.backend.Platform$LazyHolder.<clinit>(Platform.java:67)
... 25 more
According to https://github.com/google/flogger/blob/master/log4j/src/main/java/com/google/common/flogger/backend/log4j/Log4jBackendFactory.java#L30 you have to set the flogger.backend_factory
system property, so I started Java with -Dflogger.backend_factory=com.google.common.flogger.backend.slf4j.Slf4jBackendFactory#getInstance
, but this resulted in the same exception.
What am I missing?
(the whole project can be found at: https://github.com/PascalSchumacher/flogger-slf4j-test)
jdk1.8.0_181.jdk
<dependency>
<groupId>com.google.flogger</groupId>
<artifactId>flogger</artifactId>
<version>0.3.1</version>
</dependency>
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.google.common.flogger.backend.Platform.getCallerFinder(Platform.java:142)
at com.google.common.flogger.FluentLogger.forEnclosingClass(FluentLogger.java:70)
at io.tapwater.server.GrpcServer.<clinit>(GrpcServer.java:13)
Caused by: java.lang.IllegalStateException: No logging platforms found:
com.google.common.flogger.backend.system.DefaultPlatform: java.lang.ClassNotFoundException: com.google.common.flogger.backend.system.DefaultPlatform
at com.google.common.flogger.backend.Platform$LazyHolder.loadFirstAvailablePlatform(Platform.java:99)
at com.google.common.flogger.backend.Platform$LazyHolder.<clinit>(Platform.java:67)
... 3 more
Given that log4j backend was added recently (#4) it should be straight forward to add log4j2 backend.
Let me be a creator of the first issue of this project with high potential.
Incompatible flag --incompatible_load_java_rules_from_bzl will break Flogger once Bazel 1.2.1 is released.
Please see the following CI builds for more information:
Questions? Please file an issue in https://github.com/bazelbuild/continuous-integration
Important: Please do NOT modify the issue title since that might break our tools.
Thought I'd bring this to your attention, but flogger is not an original word. I don't think it was intentional, but I remembered seeing the word used in exchange with "drawing and quartering" which is the act of corporal punishment. A simple google search of "flogger" definitely raised an eyebrow.
See flagellation and the urban dictionary for flogger. Note the definition may be NSFW.
I think it was just meant to be a combination of "fluent + logger" and the result was unintended. Anyways, feel free to close this.
Coming from SLF4J/Logback, I am now lokking into flogger and log4j2 for future work...
While log4j2 is quite bulky and I like flogger's modern design, I was wondering if you'd be interested in an extension to log which returns the logged value? In log4j2, ther is a method called traceExit(T):T which does exactly that. For flogger I'd imagine something like returning(T):T
which just calls log(T) and returns T, maybe with an optional text but not too much stuff. ;-)
return log4j2.traceExit("foo");
Exit with(foo)
Additionally, log4j provides the tracing of an entry-message to have a handle for the tracing of exit to be clear of input -> output... also a nice idea...
EntryMessage entryMessage = log4j2.traceEntry("entry-msg {}", "some-param");
// ...
return log4j2.traceExit(entryMessage, "result");
Enter entry-msg some-param
...
Exit entry-msg some-param: result
What Du you think about that? Would that fit into flogger? For example like that:
<T> T returning(T val){
log("Returning: %s", val);
return val;
}
<T> T returning(T val, String message){
log("Returning [%s]: %s", message, val);
return val;
}
flogger git:(master) โ bazel sync
INFO: Invocation ID: b82bf732-b778-417e-96ed-7fc4713e7191
ERROR: error loading package '': Encountered error while reading extension file 'workspace_defs.bzl': no such package '@google_bazel_common//': The native http_archive rule is deprecated. load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") for a drop-in replacement.
Use --incompatible_remove_native_http_archive=false to temporarily continue using the native rule.
Building: no action
Fetching @google_bazel_common; fetching
Currently both flogger
and flogger-system-backend
have a default (compile
) dependency on com.google.code.findbugs:jsr305
which means it is packaged with every application. It this not required as Findbugs annotations are not required to run flogger. A better solution would be to either declare the dependency as optional
or change the scope to provided
.
When using this repo as a Bazel external dependency:
git_repository(
name = "google_bazel_common",
commit = "fe3a28b3fd66bd6d0e1b6736efd886056cd1c8cc", # head
remote = "https://github.com/google/bazel-common.git",
)
git_repository(
name = "flogger",
remote = "https://github.com/google/flogger.git",
tag = "flogger-0.2",
)
Attempting to build the main artifact:
$ bazel build @flogger//google:flogger
ERROR: /private/var/tmp/_bazel_blah/7a13dd7a63acf54d11ec8dedf378ff73/external/google_bazel_common/testing/test_defs.bzl:87:9: name 'android_library' is not defined
ERROR: Skipping '@flogger//google:flogger': error loading package '@flogger//google': Extension 'testing/test_defs.bzl' has errors
The cause is clear. @flogger//google/BUILD loads the test_defs.bzl file from bazel-common, and that file does not parse. The references to android_library
and android_local_test
here need to be prefixed with native
.
(I'm filing this with Flogger rather than bazel-common because bazel build @google_bazel_common//...
actually works. The repo doesn't import the broken file anywhere.)
I just want to know details of its advantage, where to get the information?
While writing a backend for SLF4J, I stumbled across the Flogger concept of Metadata and Tags, which seem like they would map very well to SLF4J's concept of MDC. However, while I can see that one receives the Metadata and Tags in various places, my search has not turned up any way to actually set them.
It would be very helpful if someone could drop a few lines of code showing how to set a simple Tag to point me in the right direction so I could implement the parsing/delegating of it in the SLF4J backend.
At first glance, this looked like an exciting new library. I really like the approaches to both API and performance concerns. But upon closer inspection, it looks like there are literally no backends supported other than to the ancient and long since totally abandoned Log4J project (not even Log4J 2). I am surprised that none of the current generation backends are supported, nor a general purpose framework like SLF4J. Is this library designed to only be used with legacy projects, or am I simply missing documentation on how to use other backends ?
ps.: I saw there is a logback backend project, but it's also been abandoned and is not available on Nexus, so I'm still very confused as to the status of this project in regards to projects with modern logging backends.
We want to use Flogger in Gerrit where we currently use slf4j with a log4j backend. We want to continue using log4j as backend so that the switch to Flogger is transparent for existing Gerrit installations and existing log4j configurations continue to work.
I think there is an issue in your implementation when the configuration is changed dynamically. Your implementation read the configuration twice, once in at(Level)
and once later in log()
so the logger can check the level of one configuration and log using another newly updated configuration.
To fix this issue, you can read the configuration once in at()
and propagate the configuration as a parameter of the Context.
GoogleLogger source is available in the repository, but it's not included in the Flogger Maven artifact.
According to FluentLogger.java (flogger v0.4)
public Api at(Level level) {
boolean isLoggable = isLoggable(level);
boolean isForced = Platform.shouldForceLogging(getName(), level, isLoggable);
return (isLoggable || isForced) ? new Context(level, isForced) : NO_OP;
}
when isForced true, if we could customize level, e.g. -Dflogger_level_on_forced=FINE, then more log will be outputted for debugging.
Maybe I missed it, but had rally hard time integrating slf4js. I added correct dependencies, but default logger factory was used.
After debugging and diggind through source, I found out that I need to add system property:
-Dflogger.backend_factory=com.google.common.flogger.backend.slf4j.Slf4jBackendFactory#getInstance
I have not found mention of this anywhere. I would be nice to have it mentioned in the docs.
Thanks for publishing the flogger libraries on Maven central
https://search.maven.org/#search%7Cga%7C1%7Ccom.google.flogger
Do you have documentation on which of these libraries contain which functionality ?
We are considering to migrate JGit from using slf4j API to flogger API and replace current usage
of log4 backend by using a flogger logging backend. I am not sure which of the flogger binaries
I would need to add as a dependency to JGit in order to achieve this goal.
The package javadocs are currently very generic and don't really help to answer this question.
-Matthias
Is there an example of flogger about how to log a file? thanks
Currently flogger-log4j-backend:jar:0.3.1
depends on guava:jar:25.0-jre
.
Please consider removing the dependency because:
ImmutableMap
is being used from Guava (apart from the unit tests).I am wondering what are the good arguments for the other point of view. If this dependency can and should be removed, I am happy to provide a pull request.
Hi,
I'm new to flogger. Thanks for this wonderful fluent logger.
Currently, I use atMostEvery()
often by calling logger.at(level).atMostEvery(time, TimeUnit.MILLISECONDS).log(message);
Is there's a way to customize the following context statement that are being appended to every log statement ?
[CONTEXT ratelimit_period="2000 MILLISECONDS [skipped: 2]" ]
is a bit too verbose to my taste.
I'd like to shrink it down to just [2000,2]
.
I hope I'm making a very reasonable request here :D
Thanks for any help!
Hi, could a 0.5 release be done please? It includes log4j2 support.
CallerFinder should use the StackWalker API when available (Java 9+) to avoid the exception. This can easily be solved with Multi-Release JAR Files which are available on Java 9+.
As with Guava, provide an automatic module name to avoid using the JAR name ('flogger') as the module name.
Guava: Automatic-Module-Name: com.google.common
Proposed for flogger: Automatic-Module-Name: com.google.common.flogger
Incompatible flag --incompatible_no_implicit_file_export will break Flogger once Bazel 1.2.1 is released.
Please see the following CI builds for more information:
Questions? Please file an issue in https://github.com/bazelbuild/continuous-integration
Important: Please do NOT modify the issue title since that might break our tools.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.