Skip to content

Ignore newline and carriage return in the connection string file #3628

@progxaker

Description

@progxaker

Expected behavior

The connection string from the file does not cause any errors.

Actual behavior

If the connection string is used from a file, the following warning appears:

QuickPulsePingSender warning
2024-04-05 20:10:44.668Z INFO  c.m.applicationinsights.agent - Application Insights Java Agent 3.5.2-SNAPSHOT started successfully (PID 1, JVM running for 5.792 s)
2024-04-05 20:10:44.673Z INFO  c.m.applicationinsights.agent - Java version: 17.0.10, vendor: Eclipse Adoptium, home: /opt/java/openjdk
2024-04-05 20:10:46.471Z WARN  c.a.m.o.e.i.q.QuickPulsePingSender - Pinging live metrics endpoint: Unable to parse url [https://eastus.livediagnostics.monitor.azure.com/
/QuickPulseService.svc/ping?ikey=<key>] (https://eastus.livediagnostics.monitor.azure.com/
/QuickPulseService.svc) (future warnings will be aggregated and logged once every 5 minutes)
java.lang.IllegalArgumentException: Unable to parse url [https://eastus.livediagnostics.monitor.azure.com/
/QuickPulseService.svc/ping?ikey=<key>]
  at reactor.netty.http.client.UriEndpointFactory.createUriEndpoint(UriEndpointFactory.java:69)
  at reactor.netty.http.client.UriEndpointFactory.createUriEndpoint(UriEndpointFactory.java:45)
  at reactor.netty.http.client.HttpClientConnect$HttpClientHandler.<init>(HttpClientConnect.java:509)
  at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:208)
  at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
  at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53)
  at reactor.core.publisher.Mono.subscribe(Mono.java:4490)
  at reactor.core.publisher.Mono.block(Mono.java:1741)
  at com.azure.monitor.opentelemetry.exporter.implementation.quickpulse.QuickPulsePingSender.ping(QuickPulsePingSender.java:102)
  at com.azure.monitor.opentelemetry.exporter.implementation.quickpulse.QuickPulseCoordinator.ping(QuickPulseCoordinator.java:100)
  at com.azure.monitor.opentelemetry.exporter.implementation.quickpulse.QuickPulseCoordinator.run(QuickPulseCoordinator.java:53)
  at java.base/java.lang.Thread.run(Thread.java:840)
  Suppressed: java.lang.Exception: #block terminated with an error
          at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:100)
          at reactor.core.publisher.Mono.block(Mono.java:1742)
          ... 4 common frames omitted

To Reproduce

  1. Follow the documentation to configure the App Insights Java agent to retrieve a connection string from a file.
  2. Run an application.
  3. Get a warning in 2-3 seconds.

Root cause

TL;DR The Application Insights agent does not ignore newline and carriage return.

  1. I created a file in the usual way since, the other one is not described in the wiki: vi connection-string.txt.
    By default ViM saves the file with the LF line terminator.
    I assumed that the reason could be a new line (from the logs).

    https://eastus.livediagnostics.monitor.azure.com/
    /QuickPulseService.svc/ping
    
  2. I tested the agent with the following terminators to prove my theory:

    # file applicationinsights*
    applicationinsights-connection-string_cr-eol.txt:  ASCII text, with CR line terminators
    applicationinsights-connection-string_no-eol.txt:  ASCII text, with no line terminators
    applicationinsights-connection-string.txt:         ASCII text
    applicationinsights-connection-string_windows.txt: ASCII text, with CRLF line terminators
    

    and the warning disappeared only with no line terminators.

  3. When I removed the "/" character at the end of the connection string, I got the following error:

IllegalArgumentException
2024-04-06 08:33:33.455Z ERROR c.m.applicationinsights.agent - Application Insights Java Agent 3.5.2-SNAPSHOT startup failed (PID 1)
/" java.lang.IllegalArgumentException: LiveEndpoint is invalid: "https://eastus.livediagnostics.monitor.azure.com
  at com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionStringBuilder.toUrlOrThrow(ConnectionStringBuilder.java:142)
  at com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionStringBuilder.setLiveEndpoint(ConnectionStringBuilder.java:122)
  at com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionStringBuilder.mapToConnectionConfiguration(ConnectionStringBuilder.java:103)
  at com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionStringBuilder.setConnectionString(ConnectionStringBuilder.java:40)
  at com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionString.lambda$parse$0(ConnectionString.java:37)
  at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
  at com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionString.parse()
  at com.microsoft.applicationinsights.agent.internal.telemetry.TelemetryClient$Builder.setConnect)
  at com.microsoft.applicationinsights.agent.internal.init.SecondEntryPoint.customize(SecondEntryP)
  at io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder.build(AutoConfiguredOpenTelemetrySdkBuilder.java:424)
  at io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller.installOpenTelemetrySdk(OpenTelemet)
  at io.opentelemetry.javaagent.tooling.AgentInstaller.installBytebuddyAgent(AgentInstaller.java:122)
  at io.opentelemetry.javaagent.tooling.AgentInstaller.installBytebuddyAgent(AgentInstaller.java:102)
  at io.opentelemetry.javaagent.tooling.AgentStarterImpl.start(AgentStarterImpl.java:99)
  at io.opentelemetry.javaagent.bootstrap.AgentInitializer$1.run(AgentInitializer.java:53)
  at io.opentelemetry.javaagent.bootstrap.AgentInitializer$1.run(AgentInitializer.java:47)
  at io.opentelemetry.javaagent.bootstrap.AgentInitializer.execute(AgentInitializer.java:64)
  at io.opentelemetry.javaagent.bootstrap.AgentInitializer.initialize(AgentInitializer.java:46)
  at io.opentelemetry.javaagent.OpenTelemetryAgent.startAgent(OpenTelemetryAgent.java:57)
  at io.opentelemetry.javaagent.OpenTelemetryAgent.premain(OpenTelemetryAgent.java:45)
  at com.microsoft.applicationinsights.agent.Agent.premain(Agent.java:38)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:491)
  at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:503)
Caused by: java.net.MalformedURLException: Illegal character found in host: CR
  at java.base/java.net.URL.<init>(URL.java:708)
  at java.base/java.net.URL.<init>(URL.java:569)
  at java.base/java.net.URL.<init>(URL.java:516)
  at com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionStringBuilder.toUrlOrThrow(ConnectionStringBuilder.java:134)
  ... 26 common frames omitted
Caused by: java.lang.IllegalArgumentException: Illegal character found in host: CR
  at java.base/java.net.URLStreamHandler.setURL(URLStreamHandler.java:515)
  at java.base/java.net.URLStreamHandler.parseURL(URLStreamHandler.java:326)
  at java.base/java.net.URL.<init>(URL.java:703)
  ... 29 common frames omitted
  1. So, I started looking into the SecondEntryPoint class.
    I added test output and got that the connection string already had a newline.
    I then searched for ${file:, since I assumed that the problem was occurring in the file read function.
    The following line appeared to be the root cause:

I'm preparing a pull request with a fix and new tests to solve the problem.

System information

Please provide the following information:

  • SDK Version: 3.4.19, 3.5.1, 3.5.2
  • OS type and version: Xubuntu 22.04.4 LTS x86_64
  • Application Server type and version (if applicable): N/A
  • Using spring-boot? No.
  • Additional relevant libraries (with version, if applicable): N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions