2

I have been at this all day and not getting it to work after trying so many combinations. At the end of the day, I am looking for an explicit list of steps to get JSON logging from Karaf. I have even gone through the Maven Karaf plugin source code trying to sort this out, though perhaps I didn't look far enough.

I am using Karaf 4.2.6. I am attempting to build a Karaf deployment using the karaf-maven-plugin, version 4.2.6.

If I change my layout.type for various appenders to JsonLayout, I get a stacktrace saying it can't load the JSON layout because I am missing a class. java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/ser/FilterProvider.

I looked at the jar org.ops4j.pax.logging/pax-logging-log4j2/1.10.2 and found I needed 3 Jackson jars, Core v2.8.7, Annotations v2.8.0, and Databind v2.8.7.

I have been trying to get these files in etc/startup.properties with either the start level of 5 or the start level of 8 so that they are ready for org.ops4j.pax.logging/pax-logging-log4j2/1.10.2 when it starts. I made sure they were in the system folder in the correct place. Most of the time, if I did get them into etc/startup.properties, they had a start level of 30. I placed them in a feature with the correct start levels, but they were either started well after whatever used startup.properties or just never showed up. I tried many possibly combinations, startupBundles, startupFeatures, bootFeatures, but nothing got it in startup.properties. I could not figure out how the contents of startup.properties got generated. Sometimes the features I wanted for my application wouldn't even start because something about the configuration got blocked on setting up the logging if I just placed references to those jars in startup.properties, for example

mvn\:com.fasterxml.jackson.core/jackson-core/2.8.7 = 5

Below is my pom.xml with somethings from previous attempts commented out:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <properties>
      <my_version>0.0.0</my_version>
      <myapp_common_version>0.0.0</myapp_common_version>
    </properties>    

    <groupId>com.me.myapp</groupId>
    <artifactId>myapp-karaf</artifactId>
    <version>${my_version}</version>
    <packaging>karaf-assembly</packaging>

    <name>myapp-karaf</name>
    <description>myapp-karaf details</description>

    <repositories>
        <!-- Apache ServiceMix repository (for region) -->
        <repository>
            <id>apache.servicemix.m2</id>
            <name>Apache ServiceMix M2 repository</name>
            <url>http://svn.apache.org/repos/asf/servicemix/m2-repo</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <!-- OPS4J SNAPSHOT repository -->
        <repository>
            <id>ops4j.sonatype.snapshots.deploy</id>
            <name>OPS4J snapshot repository</name>
            <url>https://oss.sonatype.org/content/repositories/ops4j-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <!-- Apache SNAPSHOT -->
        <repository>
            <id>apache.snapshots.deploy</id>
            <name>Apache snapshot repository</name>
            <url>https://repository.apache.org/content/groups/snapshots-group</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.apache.karaf.features</groupId>
            <artifactId>framework</artifactId>
            <version>4.2.6</version>
            <type>kar</type>
        </dependency>
        <dependency>
            <groupId>org.apache.karaf.features</groupId>
            <artifactId>standard</artifactId>
            <version>4.2.6</version>
            <classifier>features</classifier>
            <type>xml</type>
        </dependency>
        <dependency>
            <groupId>org.apache.karaf.features</groupId>
            <artifactId>spring</artifactId>
            <version>4.2.6</version>
            <classifier>features</classifier>
            <type>xml</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.karaf.features</groupId>
            <artifactId>enterprise</artifactId>
            <version>4.2.6</version>
            <classifier>features</classifier>
            <type>xml</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.me.myapp</groupId>
            <artifactId>myapp-common-feature</artifactId>
            <version>${myapp_common_version}</version>
            <classifier>features</classifier>
            <type>xml</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.me.myapp</groupId>
            <artifactId>myapp-feature</artifactId>
            <!-- Annoyingly this cannot come from an environment variable -->
            <version>${my_version}</version>
            <classifier>features</classifier>
            <type>xml</type>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>${env.MYAPP_SOURCE_HOME}/myapp-common/server/karaf/assembly</directory>
                <filtering>false</filtering>
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/filtered-resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>
        </resources>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.karaf.tooling</groupId>
                    <artifactId>karaf-maven-plugin</artifactId>
                    <version>4.2.6</version>
                    <extensions>true</extensions>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>process-resources</id>
                        <goals>
                            <goal>resources</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.karaf.tooling</groupId>
                <artifactId>karaf-maven-plugin</artifactId>
                <configuration>
                    <startupBundles> <!--
                        <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/2.8.0</bundle>
                        <bundle>mvn:com.fasterxml.jackson.core/jackson-core/2.8.7</bundle>
                        <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/2.8.7</bundle> -->
                    </startupBundles>
                    <installedFeatures>
                    </installedFeatures>
                    <startupFeatures>
                        <feature>com.me.myapp/${my_version}</feature>
                    </startupFeatures>
                    <bootFeatures>
                        <feature>com.me.myapp.logging.provider/${myapp_common_version}</feature>
                        <!-- standard distribution -->
                        <!-- <feature>standard</feature> -->
                        <!-- minimal distribution -->
                        <!--<feature>minimal</feature>-->
                        <feature>jaas</feature>
                        <feature>shell</feature>
                        <feature>ssh</feature>
                        <feature>management</feature>
                        <feature>bundle</feature>
                        <feature>config</feature>
                        <feature>deployer</feature>
                        <feature>diagnostic</feature>
                        <feature>instance</feature>
                        <feature>kar</feature>
                        <feature>wrap</feature>
                        <feature>log</feature>
                        <feature>package</feature>
                        <feature>service</feature>
                        <feature>system</feature>

                    </bootFeatures>
                    <javase>1.8</javase>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

com.me.myapp.logging.provider contains the Jackson jars with the proper start level.

I am running my containers in Kubernetes and want standard log collection in Kubernetes to work. I am using using an extra plugin on the logs collector to at least separate things somewhat into a JSON format, but it is error prone and I'd rather just start with JSON formatted logs rather than processing later downstream so I can separate components of the log, such as person who did the operation, at the time of logging.

I have searched on Stack Overflow, have Googled, and found hints, but no explicit steps that lead to a solution. I realize there is not an explicit listing of files here, but, as I said, I went through many combinations. Any help would be MUCH appreciated. I will also post on the Karaf user group.

Keith
  • 337
  • 3
  • 12
  • 1
    https://ops4j1.jira.com/browse/PAXLOGGING-260 fixes pax-logging-log4j2-extra, which is a fragment bundle that "brings" extra imports to original pax-logging-log4j2. Did you add this extra fragment? Karaf's https://github.com/apache/karaf/blob/master/assemblies/features/framework/src/main/feature/feature.xml doesn't include this extra fragment. – Grzegorz Grzybek Apr 29 '20 at 05:14
  • Added it, Still failing. Going to try a few things to see if I can at least get something work manually. I notice that the imports in extra have no versions in the optional imports, and I have a newer version of Jackson in my application. Perhaps my current problem comes from that, am going to look at the OSGi manifests of pax-log4j2 and extra. Still trying to understand how things get into startup.properties. If you have any ideas @GrzegorzGrzybek, please let me know. – Keith Apr 29 '20 at 15:35
  • 1
    The only thing I can suggest is to check Pax Logging 1.11.x Karaf tests in https://github.com/ops4j/org.ops4j.pax.logging/tree/pax-logging-1.11.x/pax-logging-it-karaf/karaf-it/src/test/java/org/ops4j/pax/logging/it/karaf - there are tests for present and missing "extra" bundle. – Grzegorz Grzybek Apr 30 '20 at 07:24

3 Answers3

6

OK, after several days, I figured out everything that needed to be done. Thank you @GrzegorzGrzybek for the help.

I needed the following lines

mvn\:org.ops4j.pax.logging/pax-logging-log4j2-extra/1.11.4 = 8
mvn\:com.fasterxml.jackson.core/jackson-core/2.9.10 = 8
mvn\:com.fasterxml.jackson.core/jackson-annotations/2.9.10 = 8
mvn\:com.fasterxml.jackson.core/jackson-databind/2.9.10 = 8

added to my etc/startup.properties. If I just edited the file to add them, and made sure I had the files in the system repository, it would not work. No idea, some entry was not being made somewhere else in the etc configs so either the container wouldn't start, or some feature sets were being started up before the wrap handler was installed, so the whole container would grind to a halt.

I tried lots of combinations, but finally found how to get things into etc/startup.properties. I placed the bundles I wanted into their own feature with the start level I wanted them to have.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.3.0" name="myapp-common-container-feature">
  <feature name="com.me.myapp.logging.provider" version="0.12.0" description="MyApp Logging Provider">
    <bundle start-level="8">mvn:com.fasterxml.jackson.core/jackson-annotations/2.9.10</bundle>
    <bundle start-level="8">mvn:com.fasterxml.jackson.core/jackson-core/2.9.10</bundle>
    <bundle start-level="8">mvn:com.fasterxml.jackson.core/jackson-databind/2.9.10</bundle>
    <bundle start-level="8">mvn:org.ops4j.pax.logging/pax-logging-log4j2-extra/1.11.4</bundle>
  </feature>
</features>

Notice the start-level attribute.

Then, in my assembly POM, I put the following dependency:

        <dependency>
            <groupId>com.me.myapp</groupId>
            <artifactId>myapp-common-container-feature</artifactId>
            <version>0.12.0</version>
            <classifier>features</classifier>
            <type>xml</type>
            <scope>compile</scope>
        </dependency>

The important line here is <scope>compile</scope>. Features in the compile scope will be placed in startup.properties if placed in <startupFeatures /> in the configuration for the Karaf Maven Plugin.

            <plugin>
                <groupId>org.apache.karaf.tooling</groupId>
                <artifactId>karaf-maven-plugin</artifactId>
                <configuration>
                  <startupFeatures>                
                    <feature>com.me.myapp.logging.provider/0.12.0</feature>
                  </startupFeatures>

Now the container starts up with JSON logging.

Keith
  • 337
  • 3
  • 12
1

On my side, I followed Keith's answer but this was not sufficient as I had already another older version of Jackson in the OSGI container.

Here is what I did:

Added the log4j2 extra with the three Jackson libs (version 1.11.13 of Pax-Logging + jackson version 2.12.4) in the startup.properties:

mvn\:com.fasterxml.jackson.core/jackson-annotations/2.12.4 = 6
mvn\:com.fasterxml.jackson.core/jackson-core/2.12.4 = 6
mvn\:com.fasterxml.jackson.core/jackson-databind/2.12.4 = 6
mvn\:org.ops4j.pax.logging/pax-logging-log4j2-extra/1.11.13 = 6
mvn\:org.ops4j.pax.logging/pax-logging-api/1.11.13 = 8
mvn\:org.ops4j.pax.logging/pax-logging-log4j2/1.11.13 = 8

And in the overrides.properties:

mvn:com.fasterxml.jackson.core/jackson-core/2.12.4;range="[2,3)"
mvn:com.fasterxml.jackson.core/jackson-databind/2.12.4;range="[2,3)"
mvn:com.fasterxml.jackson.core/jackson-annotations/2.12.4;range="[2,3)"

and only after this I was able to see my Json log properly formatted (with JsonLayout deprecated way).

I also tried the new way by trying to deploy bundle log4j-layout-template-json but it seems this lib is wrongly released (host fragment is referring to itself).

рüффп
  • 5,172
  • 34
  • 67
  • 113
0

I put these jars in system repository, installed using wraper and restarted karaf. It's worked for me:

bundle:install 'wrap:mvn:org.ops4j.pax.logging/pax-logging-log4j2-extra/1.11.4'
bundle:install 'wrap:mvn:com.fasterxml.jackson.core/jackson-core/2.9.10'
bundle:install 'wrap:mvn:com.fasterxml.jackson.core/jackson-annotations/2.9.10'
bundle:install 'wrap:mvn:com.fasterxml.jackson.core/jackson-databind/2.9.10'
  • Normally wrapper is for libraries that does not have the bundle manifest, but as far as I know the jackson and log4j extra are deployable in OSGI without need of "wrap". – рüффп Jan 06 '22 at 14:00