Search code examples
javakotlinkubernetesprometheusjib

Adding prometheus jmx agent jar to JIB build


I need to add the "jmx_prometheus_javaagent" jar to JIB build but I get the following error when I deploy the application:

Error opening zip file or JAR manifest missing : /srv/jmx_prometheus_javaagent-0.16.1.jar
Error occurred during initialization of VM
agent library failed to init: instrument

I have added the jar and a config file in the required directory and these are the relevant change I did in my build.gradle.kts:

val jibExtraDir = file("$buildDir/jib-extra")
val jibAppRoot = "/srv"

val copyJmxPrometheusJavaAgent by tasks.registering(Copy::class) {
    val jarName = "jmx_prometheus_javaagent-0.16.1.jar"
    val configName = "jmx_prometheus_config.yaml"
    from("${project.projectDir.absolutePath}/resources/jmx-prometheus")
    into("$jibExtraDir/$jibAppRoot")
    doLast {
        // Required for reproducible builds.
        file("$jibExtraDir/$jibAppRoot/$jarName").setLastModified(0)
        file("$jibExtraDir/$jibAppRoot/$configName").setLastModified(0)
    }
}

subProjects {
    plugins.withType<JibPlugin>().configureEach {
        container {
            jvmFlags = listOf(
                           "-javaagent:$jibAppRoot/jmx_prometheus_javaagent-0.16.1.jar=8099:$jibAppRoot/jmx_prometheus_config.yaml"
                       )
        }
        tasks.withType<JibTask> {
            dependsOn(":copyJmxPrometheusJavaAgent")
        }
}

This is my jmx_prometheus_config.yaml:

---
lowercaseOutputName: true
whitelistObjectNames: [
    "java.lang:type=Memory",
    "java.lang:type=GarbageCollector,*"
]

The error message states that the JAR manifest is missing. But since the directory structure I added in the JIB looks alright, I am not sure what I am doing wrong here.


Solution

  • You are copying the agent files from resources/jmx-prometheus/* into <project root>/build/jib-extra/srv, but that just ends there. Jib isn't putting those files into a built image.

    Since the default Jib "extra directories" is src/main/jib, technically, you can simply copy the files into src/main/jib/.... However, I assume you don't want to check in the files into the source directory, so you will probably want to configure the Jib extra directory like this:

            container {
                jvmFlags = ...
            }
            extraDirectories {
                paths {
                    path {
                        setFrom("$jibExtraDir")
                    }
                }
            }
    

    or

    extraDirectories.paths = "$jibExtraDir"
    

    See this doc for more information about the extraDirectories configuration.

    Also, here's a Jib sample that dynamically downloads and copies a Java agent.


    Tip: dive is a very handy tool to inspect the contents of a build image. Use it to verify whether the files are correctly copied into an image.