本文介绍了使用 Application Insights 的 Java 代理来检测 Java 应用程序时可能会遇到的一些常见问题。 本文还介绍了解决这些问题的步骤。 Application Insights 是 Azure Monitor 平台服务的一项功能。
检查自诊断日志文件
默认情况下,Application Insights Java 3.x 在保存 applicationinsights-agent-3.2.11.jar
文件的同一目录中生成名为 applicationinsights.log
的日志文件。
针对你可能遇到的问题查找线索时,此日志文件是要检查的第一个位置。
如果未生成日志文件,请检查 Java 应用程序是否对保存 applicationinsights-agent-3.2.11.jar
文件的目录具有写入权限。
如果仍未生成日志文件,请检查 Java 应用程序的 stdout 日志。 Application Insights Java 3.x 应将任何错误记录到 stdout,以阻止将其记录到正常位置。
JVM 无法启动
如果 JVM 无法启动并显示“打开 zip 文件时出错或缺少 JAR 清单”,请尝试重新下载代理 jar 文件,因为它在文件传输过程中可能已损坏。
从 Application Insights Java 2.x SDK 进行升级
如果你已在应用程序中使用 Application Insights Java 2.x SDK,则可以继续使用它。 Application Insights Java 3.x 代理会检测到它,并捕获和关联你通过 2.x SDK 发送的任何自定义遥测,同时禁止 2.x SDK 执行的任何自动收集以防止重复遥测。 有关详细信息,请参阅从 Java 2.x SDK 进行升级。
从 Application Insights Java 3.0 预览版进行升级
如果要从 Java 3.0 预览版代理进行升级,请仔细检查所有配置选项。 JSON 结构在 3.0 正式发布版 (GA) 中已完全更改。
这些更改包括:
- 配置文件名称已从
ApplicationInsights.json
更改为applicationinsights.json
。 instrumentationSettings
节点不再存在。instrumentationSettings
中的所有内容已移动到根级别。sampling
、jmxMetrics
、instrumentation
和heartbeat
等配置节点已从preview
移出到根级别。
某些日志记录不是自动收集的
日志记录首先要符合为日志记录框架配置的级别,其次还要符合为 Application Insights 配置的级别,只有在这种情况下才会捕获日志记录。
例如,如果将日志记录框架配置为从包 com.example
记录 WARN
(和更高版本),并将 Application Insights 配置为捕获 INFO
(和更高版本),则 Application Insights 将只从包 com.example
捕获 WARN
(和更高版本)。
若要了解某个特定的日志记录语句是否满足日志记录框架的已配置阈值,最好的方法是确认它是否显示在正常的应用程序日志(例如文件或控制台)中。
另请注意,如果将异常对象传递到记录器,则日志消息(和异常对象详细信息)会显示在 Azure 门户中的 exceptions
表(而不是 traces
表)下。
有关更多详细信息,请参阅自动收集的日志记录配置。
导入 SSL 证书
本部分帮助你在使用 Java 代理时进行故障排除,并可能会修复与 SSL 证书相关的异常。
下面有两种不同的方法可以解决这个问题:
- 如果使用的是默认 Java 密钥存储
- 如果使用的是自定义 Java 密钥存储
如果不确定要使用哪种方法,请检查是否有 JVM 参数 -Djavax.net.ssl.trustStore=...
。
如果没有这样的 JVM 参数,则可能使用的是默认 Java 密钥存储。
如果确实有这样的 JVM 参数,则可能使用的是自定义密钥存储,JVM 参数会将你指向自定义密钥存储。
如果使用的是默认 Java 密钥存储:
通常情况下,默认的 Java 密钥存储已具有所有 CA 根证书。 但是,可能有一些例外情况,例如,引入终结点证书可能由不同的根证书进行签名。 因此,我们建议使用以下三个步骤来解决此问题:
检查用于对 Application Insights 终结点进行签名的 SSL 证书是否已存在于默认密钥存储中。 默认情况下,受信任的 CA 证书存储在
$JAVA_HOME/jre/lib/security/cacerts
中。 若要列出 Java 密钥存储中的证书,请使用以下命令:keytool -list -v -keystore $PATH_TO_KEYSTORE_FILE
你可以将输出重定向到这样的一个临时文件(稍后可以轻松搜索)
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts > temp.txt
获得证书列表后,按照以下步骤下载用于对 Application Insights 终结点进行签名的 SSL 证书。
下载证书后,使用以下命令基于证书生成 SHA-1 哈希:
keytool -printcert -v -file "your_downloaded_ssl_certificate.cer"
复制 SHA-1 值并检查此值是否存在于你之前保存的“temp.txt”文件中。 如果在临时文件中找不到 SHA-1 值,则表示默认 Java 密钥存储中缺少下载的 SSL 证书。
使用以下命令将 SSL 证书导入到默认 Java 密钥存储:
keytool -import -file "the cert file" -alias "some meaningful name" -keystore "path to cacerts file"
在本例中,该证书是
keytool -import -file "your downloaded ssl cert file" -alias "some meaningful name" $JAVA_HOME/jre/lib/security/cacerts
如果使用的是自定义 Java 密钥存储:
如果使用的是自定义 Java 密钥存储,则你可能需要将 Application Insights 终结点 SSL 证书导入其中。 建议你执行以下两个步骤来解决此问题:
- 按照以下步骤从 Application Insights 终结点下载 SSL 证书。
- 使用以下命令将 SSL 证书导入到自定义 Java 密钥存储:
keytool -importcert -alias your_ssl_certificate -file "your downloaded SSL certificate name.cer" -keystore "Your KeyStore name" -storepass "Your keystore password" -noprompt
下载 SSL 证书的步骤
打开最喜欢的浏览器,转到要从中下载 SSL 证书的 URL。
选择浏览器中的“查看站点信息”(锁)图标,然后选择“证书”选项。
然后,你必须单击“证书路径”-> 选择该根证书 -> 单击“查看证书”。 这会弹出一个新的证书菜单,你可以通过此新菜单来下载证书。
转到“详细信息”选项卡,然后选择“复制到文件”。
选择“下一步”按钮,选择“Base-64 编码的 X.509 (.CER)”格式,然后再次选择“下一步”。
指定要在其中保存 SSL 证书的文件。 然后,选择“下一步”>“完成”。 应该会看到“导出成功”消息。
了解 UnknownHostException
如果在升级到高于 3.2.0 的 Java 代理版本后看到此异常,则升级网络以解析异常中显示的新终结点可能会解决该异常。 Application Insights 各版本之间存在差异的原因是,与旧版 v2/track
相比,高于 3.2.0 的版本指向新的引入终结点 v2.1/track
。 新的引入终结点会自动将你重定向到离你的 Application Insights 资源的存储最近的引入终结点(异常中显示的新终结点)。
缺少密码套件
如果 Application Insights Java 代理检测到你没有它所连接到的终结点支持的任何密码套件,它将在此处发出警报并连接你。
密码套件的背景:
密码套件在客户端应用程序和服务器通过 SSL/TLS 连接交换信息之前发挥作用。 客户端应用程序启动 SSL 握手。 在该过程中,会通知服务器它支持哪些密码套件。 服务器接收该信息,并将客户端应用程序支持的密码套件与它支持的算法进行比较。 如果找到匹配项,服务器会通知客户端应用程序并建立安全连接。 如果找不到匹配项,服务器将拒绝连接。
如何确定客户端密码套件:
在这种情况下,客户端是正在运行检测到的应用程序的 JVM。 从 3.2.5 开始,如果缺少密码套件可能导致与其中一个服务终结点的连接失败,Application Insights Java 将一条记录警告消息。
如果使用早期版本的 Application Insights Java,请编译并运行以下 Java 程序,以获取 JVM 中支持的密码套件列表:
import javax.net.ssl.SSLServerSocketFactory;
public class Ciphers {
public static void main(String[] args) {
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
String[] defaultCiphers = ssf.getDefaultCipherSuites();
System.out.println("Default\tCipher");
for (int i = 0; i < defaultCiphers.length; ++i) {
System.out.print('*');
System.out.print('\t');
System.out.println(defaultCiphers[i]);
}
}
}
以下是 Application Insights 终结点通常支持的密码套件:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
如何确定服务器端密码套件:
在这种情况下,服务器端是 Application Insights 引入终结点或 Application Insights 实时指标终结点。 可以使用 SSLLABS 等联机工具根据终结点 URL 确定预期的密码套件。
如何添加缺少的密码套件:
如果使用 Java 9 或更高版本,请检查 JVM 是否在 jmods 文件夹中包含了 jdk.crypto.cryptoki
模块。 此外,如果要使用 jlink
生成自定义 Java 运行时,请确保包含这一模块。
否则,这些密码套件应已经是新式 Java 8+ 发行版的一部分,因此建议检查 Java 发行版的安装位置,并调查该 Java 发行版的 java.security
配置文件中的安全提供程序与标准 Java 发行版不同的原因。