Skip to content
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

Logging Example #58

Open
phhoef opened this issue Jun 12, 2018 · 20 comments
Open

Logging Example #58

phhoef opened this issue Jun 12, 2018 · 20 comments

Comments

@phhoef
Copy link

phhoef commented Jun 12, 2018

Could you please add a small example, that shows how to use the new, improved logging mechanism in OSGi R7.

I built a small OSGi application based on this tutorial. https://github.com/osgi/osgi.enroute/tree/master/examples/microservice

I saw, that the Logging mechanism has been improved for the R7 compendium. https://github.com/osgi/design/blob/master/rfcs/rfc0219/rfc-0219-LogService-Update.pdf on page 12

So, I added a field in my my controller class of the rest-service project.
@Reference private org.osgi.service.log.Logger _logger;

Unfortunately, OSGi is not resolving this @Reference and the field is always null.
I am quite new to the OSGi stuff, but as far as I understand the whole thing, I have to add a logging library, that implements this interface. Unfortunately I cannot find a library like log4j, logback, etc that implements the new interface. Do I have to build the bridge between the interface and the implementation or is there something ready to go?

@timothyjward
Copy link
Contributor

I saw, that the Logging mechanism has been improved for the R7 compendium.

This is true, logging has seen a big overhaul in R7.

Do I have to build the bridge between the interface and the implementation or is there something ready to go?

The best person to give answers about this is @rotty3000 who has been doing a lot of work with R7 logging. He's probably also the best person to produce an additional enRoute example.

@phhoef
Copy link
Author

phhoef commented Jun 12, 2018

thanks for your answer @timothyjward. It seems that you're involved in every project around osgi :-)
Maybe @rotty3000 could help me out and give a small example how to use the new logging interface.

Thank you

@rotty3000
Copy link
Member

rotty3000 commented Jun 12, 2018 via email

@phhoef
Copy link
Author

phhoef commented Jun 12, 2018

@rotty3000, thank your for your very quick reply :-)
Could you give me a short answer, how to use the logging service, so that I am able to proceed in the meanwhile?

I understand the following:
One should use the new Logger interface to be compatible with other bundles like ConfigAdmin.
But of course, the interface does not provide the implementation. What I don't get is, if there is a library out there like log4j etc that is already implementing this interface and I can just add this bundle as dependency or do I have to implement the bridge between the interface and the logging library myself?
Obviously there is no default implementation, otherwise I would have expected that OSGi can reference this service based on the @Reference annotation, right?
There is another point I do not completely understand. In the specification is mentioned, that the new interface is similar to the slf4j one. But do I have to use slf4j now or is it just a comparison to show the approach?

Thanks for your help :-)
OSGi is quite confusing in some points for a beginner.

@bjhargrave
Copy link
Member

bjhargrave commented Jun 12, 2018 via email

@phhoef
Copy link
Author

phhoef commented Jun 12, 2018

At least I thought, I had :-)
I read the following article
https://osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-logger.support

There is a short example in the Logger Support section.
I've put my test application on a github Repository.
As far as I can tell, I am doing the same as shown in the example snippet - at least I was trying.
https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/java/com/my/app/rest/rest/ServerInfoControllerImpl.java

I've added a field of type Logger and annotated it with @Reference.
I was hoping, that OSGi now resolves the service, but maybe I am missing something?

@timothyjward
Copy link
Contributor

I've added a field of type Logger and annotated it with @reference.
I was hoping, that OSGi now resolves the service, but maybe I am missing something?

As the example in the specification shows, you need to set the type of the reference to LoggerFactory (which is the actual service you depend on). DS will automatically then convert the service to a Logger for you:

@Reference(service=LoggerFactory.class)
Logger _logger;

@rotty3000
Copy link
Member

this

@Reference(service=LoggerFactory.class)
Logger _logger;

is currently not working on Felix SCR.

@phhoef
Copy link
Author

phhoef commented Jun 12, 2018

@timothyjward, sorry for confusion. I had set the service interface explicitly, but checked in the wrong version.

@rotty3000 so, you recommend using another SCR or is there any chance to get this working with Felix SCR?

@rotty3000
Copy link
Member

There isn't another DS impl that implements logging support to my knowledge. I've filled a bug with Felix https://issues.apache.org/jira/browse/FELIX-5865 which is already being worked on and I'm verifying a few other things. Please watch this space. This part of the DS and logging spec is new, the RIs are not yet totally stable so it will require a little patience. :)

@phhoef
Copy link
Author

phhoef commented Jun 12, 2018

thanks for the explanation @rotty3000.
Is there any workaround in order to get any kind of logging up and running, so that I am able to proceed with development?
From my current understanding it would be possible to create a temporary bundle, that implements the Logger interface and provides this service, right?
Right now, I am getting NullPointerException...

@rotty3000
Copy link
Member

You can do this:

	@Reference(service = LoggerFactory.class)
	private LoggerFactory loggerFactory;
	private Logger logger;

	@Activate
	void activate() {
		logger = loggerFactory.getLogger(getClass());
		logger.info(l -> l.info("TESTING"));
	}

However you still need a Log Service 1.5 (which is only available by equinox framework).

@rotty3000
Copy link
Member

That will work, but the issue will become log configuration.

Until this whole logging story resolves itself. I would recommend to simply use the slf4j API which has OSGi support. I believe enRoute already has logback and the slf4j API available in it's templates. I would just go with that for the time being.

@phhoef
Copy link
Author

phhoef commented Jun 12, 2018

thanks for your suggestion, but that confuses me.
Your suggestion is to just use slf4j as described here without any OSGi stuff?
I see sl4j and logback in the dependency tree, even if I do not exactly know which bundle has these dependencies.

So it would look something like this:
@Activate private org.slf4j.Logger _slf4jlogger = LoggerFactory.getLogger(ServerInfoControllerImpl.class);

@rotty3000
Copy link
Member

just like this:

private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Foo.class);

@phhoef
Copy link
Author

phhoef commented Jun 12, 2018

Thank you all for your help

@rotty3000
Copy link
Member

FYI, once the next release of Felix SCR is made the logging pattern suggested in the R7 DS spec will work (though bind and constructor injection patterns will need to wait until bnd supports DS 1.4):

	@Reference(service = LoggerFactory.class)
	private Logger logger;

	@Activate
	void activate() {
		logger.info(l -> l.info("TESTING"));
	}

@jcommand
Copy link

Hello,

I have set the configuration for my bundle to Info via Configuration Admin Service and during debugging I see that the logger has the right context, name and the desired LogLevel INFO.

if (log.isInfoEnabled()) {
log.info("set log level to: {}", LogLevel.DEBUG.name());
}

Unfortunately the message is not displayed on the console.

Do I still have to configure a console appender?

Jetty writes debug messages out a lot. And they can't be limited.
Looks like the jetty is using the old LogService. How is that now with the enRoute.
V7 spec 1.4 Logging or LogService from <= V6.

I used to log to the console myself using LogListener. Is that still the case?

Many thanks and greetings
Frank

@bjhargrave
Copy link
Member

The OSGi Log Service distributes logged information to registered LogServiceReader services or active PushStreams from the LogStreamProvider service. So you will still need a way to display logged information. You may want to look at Apache Felix Logback which does a nice job of integration the OSGi Log Service 1.4 with Logback.

@jcommand
Copy link

Thank you very much,

so far so good. Then I have to implement my own LogServiceReader which is parameterized by ConfigurationAdmin and not externally by the logback.xml.

Greeting
Frank

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants