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

Cloudwatch logger appender doesn't work with native image #1687

Open
andriy-dmytruk opened this issue Apr 18, 2023 · 0 comments
Open

Cloudwatch logger appender doesn't work with native image #1687

andriy-dmytruk opened this issue Apr 18, 2023 · 0 comments

Comments

@andriy-dmytruk
Copy link
Contributor

Issue description

Reproduce

  • Create a micronaut application (micronaut launch link).
  • Add the following dependency:
    implementation("io.micronaut.aws:micronaut-aws-cloudwatch-logging")
    
  • Modify the src/main/resources/logback.xml to be the following:
    <configuration>
      <appender name='CLOUDWATCH' class='io.micronaut.aws.cloudwatch.logging.CloudWatchLoggingAppender'>
          <groupName>MyLogGroup</groupName>
          <streamName>MyStreamName</streamName>
          <createGroupAndStream>true</createGroupAndStream>
          <encoder class='ch.qos.logback.core.encoder.LayoutWrappingEncoder'>
              <layout class='ch.qos.logback.contrib.json.classic.JsonLayout'>
                  <jsonFormatter class='io.micronaut.aws.cloudwatch.logging.CloudWatchJsonFormatter'/>
              </layout>
          </encoder>
      </appender>
    
      <root level='INFO'>
          <appender-ref ref='CLOUDWATCH'/>
      </root>
    </configuration>
  • Run ./gradlew nativeRun

Error

With the configuration in build.gradle:

graalvmNative {
    binaries.configureEach {
        buildArgs.addAll(
                "--trace-object-instantiation=java.lang.Thread"
        )
    }
}

the following exception is thrown (important lines marked):

Error: Detected a started Thread in the image heap. Threads running in the image generator are no longer running at image runtime.  Object has been initialized by the io.micronaut.runtime.Micronaut class initializer with a trace: 
 	at java.lang.Thread.<init>(Thread.java:708)
	at java.util.concurrent.Executors$DefaultThreadFactory.newThread(Executors.java:660)
	at ch.qos.logback.core.util.ExecutorServiceUtil$1.newThread(ExecutorServiceUtil.java:42)
	at java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:630)
	at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:920)
	at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1593)
	at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:346)
	at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:632)
-->  at io.micronaut.aws.cloudwatch.logging.CloudWatchLoggingAppender.start(CloudWatchLoggingAppender.java:161)
	at ch.qos.logback.core.joran.action.AppenderAction.end(AppenderAction.java:90)
	at ch.qos.logback.core.joran.spi.Interpreter.callEndAction(Interpreter.java:309)
	at ch.qos.logback.core.joran.spi.Interpreter.endElement(Interpreter.java:193)
	at ch.qos.logback.core.joran.spi.Interpreter.endElement(Interpreter.java:179)
	at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPlayer.java:62)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:165)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:152)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:110)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:53)
	at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:64)
	at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:134)
	at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84)
	at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
	at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
	at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
	at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:417)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:362)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:388)
-->  at io.micronaut.runtime.Micronaut.<clinit>(Micronaut.java:53)

The issue is caused because native image doesn't support thread creation during build time and the the appended calls scheduleAtFixedRate in the CloudWatchLoggingAppender. The appender needs to be started during build time in this case as loggers are required by Micronaut, ApplicationContext and other core classes, and the logger starts all the appenders on creation.

graemerocher pushed a commit that referenced this issue Apr 19, 2023
* Fix native image build with CloudWatchLoggingAppender
- Start the thread to send logs to cloudwatch only when append command is called, so it is not started during build time
- Create dispatchOnStart property to return to previous behavior

* Modify CloudWatchLoggingAppender tests
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

1 participant