From e3acb844f9296daa3eb2a1c20725555ed3641630 Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Tue, 9 Feb 2021 13:05:20 -0800 Subject: [PATCH 01/16] Collect system.disk.io and total processor time using oshi java library --- core/build.gradle | 1 + .../perfcounter/OshiPerformanceCounter.java | 83 +++++++++++ ...cessBuiltInPerformanceCountersFactory.java | 6 +- .../WindowsPerformanceCounterAsPC.java | 133 ------------------ 4 files changed, 87 insertions(+), 136 deletions(-) create mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java diff --git a/core/build.gradle b/core/build.gradle index 9889f39c242..3b0c4f6296d 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -86,6 +86,7 @@ dependencies { compile ([group: 'com.google.code.gson', name: 'gson', version: '2.8.2']) // update transitive dependency version compile ([group: 'com.google.guava', name: 'guava', version: '27.1-android']) + compile ([group: 'com.github.oshi', name:'oshi-core',version:'5.3.1']) compile 'org.slf4j:slf4j-api:1.7.26' testCompile group: 'org.hamcrest', name:'hamcrest-core', version:'1.3' testCompile group: 'org.hamcrest', name:'hamcrest-library', version:'1.3' diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java new file mode 100644 index 00000000000..73225aa58dc --- /dev/null +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -0,0 +1,83 @@ +/* + * ApplicationInsights-Java + * Copyright (c) Microsoft Corporation + * All rights reserved. + * + * MIT License + * Permission is hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation files (the ""Software""), to deal in the Software + * without restriction, including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE + * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package com.microsoft.applicationinsights.internal.perfcounter; + +import com.microsoft.applicationinsights.TelemetryClient; +import com.microsoft.applicationinsights.telemetry.MetricTelemetry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import oshi.SystemInfo; +import oshi.hardware.HWDiskStore; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.software.os.OSProcess; +import oshi.software.os.OperatingSystem; + +public class OshiPerformanceCounter implements PerformanceCounter { + + private static final Logger logger = LoggerFactory.getLogger(OshiPerformanceCounter.class); + private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "OshiPerformanceCounter"; + private final static double NANOS_IN_SECOND = 1000000000.0; + private long lastCollectionInNanos = -1; + private double prevProcessIO; + + @Override public String getId() { + return ID; + } + + @Override public void report(TelemetryClient telemetryClient) { + long currentCollectionInNanos = System.nanoTime(); + + SystemInfo systemInfo = new SystemInfo(); + HardwareAbstractionLayer hal = systemInfo.getHardware(); + OperatingSystem osInfo = systemInfo.getOperatingSystem(); + OSProcess processInfo = osInfo.getProcess(osInfo.getProcessId()); + + double currentProcessIO = 0.0; + + // system.disk.io + for (HWDiskStore diskStore : hal.getDiskStores()) { + currentProcessIO += (double) (diskStore.getReadBytes() + diskStore.getWriteBytes()); + } + + if (lastCollectionInNanos != -1) { + double timeElapsedInSeconds = ((double)(currentCollectionInNanos - lastCollectionInNanos)) / NANOS_IN_SECOND; + double value = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; + prevProcessIO = currentProcessIO; + send(telemetryClient, value, Constants.PROCESS_IO_PC_METRIC_NAME); + logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, value); + } + + prevProcessIO = currentProcessIO; + lastCollectionInNanos = currentCollectionInNanos; + + // runtime.java.cpu_time + processInfo.updateAttributes(); + long totalProcessorTime = (long) ((processInfo.getUserTime() + processInfo.getKernelTime()) * 0.001); + send(telemetryClient, totalProcessorTime, Constants.TOTAL_CPU_PC_METRIC_NAME); + logger.trace("Sent performance counter for '{}': '{}'", Constants.TOTAL_CPU_PC_METRIC_NAME, totalProcessorTime); + } + + private void send(TelemetryClient telemetryClient, double value, String metricName) { + MetricTelemetry telemetry = new MetricTelemetry(metricName, value); + telemetryClient.track(telemetry); + } +} diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java index cd2250b2cf8..a6071ebcbfd 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java @@ -104,13 +104,13 @@ private Collection getWindowsPerformanceCounters() { ArrayList performanceCounters = getMutualPerformanceCounters(); try { - WindowsPerformanceCounterAsPC pcWindowsPCs = new WindowsPerformanceCounterAsPC(); - performanceCounters.add(pcWindowsPCs); + OshiPerformanceCounter oshiPerfCounter = new OshiPerformanceCounter(); + performanceCounters.add(oshiPerfCounter); } catch (ThreadDeath td) { throw td; } catch (Throwable e) { try { - logger.error("Failed to create WindowsPerformanceCounterAsPC: '{}'", e.toString()); + logger.error("Failed to create OshiPerformanceCounter: '{}'", e.toString()); } catch (ThreadDeath td) { throw td; } catch (Throwable t2) { diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java deleted file mode 100644 index ad4637fb4a7..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import java.util.HashMap; -import java.util.Map; - -import com.google.common.base.Preconditions; -import com.microsoft.applicationinsights.TelemetryClient; -import com.microsoft.applicationinsights.internal.system.SystemInformation; -import com.microsoft.applicationinsights.telemetry.MetricTelemetry; - -import com.google.common.base.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Built-in Windows performance counters that are sent as {@link com.microsoft.applicationinsights.telemetry.MetricTelemetry} - * - * Created by gupele on 3/30/2015. - */ -public final class WindowsPerformanceCounterAsPC extends AbstractWindowsPerformanceCounter { - - private static final Logger logger = LoggerFactory.getLogger(WindowsPerformanceCounterAsPC.class); - - private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "WindowsPerformanceCounterAsPC"; - - // Performance counter key and its metric name that is relevant when sending. - private final HashMap pcs = new HashMap(); - - /** - * Registers the 'built-in' Windows performance counters that are not fetched from the JVM JMX. - * - * @throws java.lang.Throwable The constructor might throw an Error if the JniPCConnector is not able to properly - * connect to the native code. or Exception if the constructor is not called under Windows OS. - */ - public WindowsPerformanceCounterAsPC() throws Throwable { - Preconditions.checkState(SystemInformation.INSTANCE.isWindows(), "Must be used under Windows OS."); - - register(Constants.TOTAL_CPU_PC_CATEGORY_NAME, Constants.CPU_PC_COUNTER_NAME, Constants.INSTANCE_NAME_TOTAL, Constants.TOTAL_CPU_PC_METRIC_NAME); - register(Constants.PROCESS_CATEGORY, Constants.PROCESS_IO_PC_COUNTER_NAME, JniPCConnector.translateInstanceName(JniPCConnector.PROCESS_SELF_INSTANCE_NAME), - Constants.PROCESS_IO_PC_METRIC_NAME); - - if (pcs.isEmpty()) { - // Failed to register, the performance counter is not needed. - throw new Exception("Failed to register all built-in Windows performance counters."); - } - } - - @Override - public void report(TelemetryClient telemetryClient) { - for (Map.Entry entry : pcs.entrySet()) { - try { - double value = JniPCConnector.getValueOfPerformanceCounter(entry.getKey()); - if (value < 0) { - reportError(value, entry.getValue()); - } else { - send(telemetryClient, value, entry.getValue()); - logger.trace("Sent performance counter for '{}': '{}'", entry.getValue(), value); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable e) { - try { - if (logger.isErrorEnabled()) { - logger.error("Failed to send performance counter for '{}'", entry.getValue(), e); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t2) { - // chomp - } - } - } - } - - @Override - public String getId() { - return ID; - } - - private void send(TelemetryClient telemetryClient, double value, String metricName) { - MetricTelemetry telemetry = new MetricTelemetry(metricName, value); - telemetryClient.track(telemetry); - } - - /** - * The method will use the {@link com.microsoft.applicationinsights.internal.perfcounter.JniPCConnector} to register a performance counter. - * The method might throw an Error if the JniPCConnector is not able to properly connect to the native code. - * @param category The category - * @param counter The counter - * @param instance The instnace - */ - private void register(String category, String counter, String instance, String metricName) { - String key = JniPCConnector.addPerformanceCounter(category, counter, instance); - if (!Strings.isNullOrEmpty(key)) { - try { - pcs.put(key, metricName); - } catch (ThreadDeath td) { - throw td; - } catch (Throwable e) { - try { - if (logger.isErrorEnabled()) { - logger.error("Exception while registering windows performance counter as PC", e); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t2) { - // chomp - } - } - } - } -} From ce45eab5c3b3df060a50193fff96d337c3158e0b Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Tue, 9 Feb 2021 15:20:41 -0800 Subject: [PATCH 02/16] Send old perf using JNI for testing purpose --- ...cessBuiltInPerformanceCountersFactory.java | 3 + .../WindowsPerformanceCounterAsPC.java | 133 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java index a6071ebcbfd..217c60d104e 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java @@ -106,6 +106,9 @@ private Collection getWindowsPerformanceCounters() { try { OshiPerformanceCounter oshiPerfCounter = new OshiPerformanceCounter(); performanceCounters.add(oshiPerfCounter); + + WindowsPerformanceCounterAsPC wpc = new WindowsPerformanceCounterAsPC(); + performanceCounters.add(wpc); } catch (ThreadDeath td) { throw td; } catch (Throwable e) { diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java new file mode 100644 index 00000000000..1ffe46d7da1 --- /dev/null +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java @@ -0,0 +1,133 @@ +/* + * ApplicationInsights-Java + * Copyright (c) Microsoft Corporation + * All rights reserved. + * + * MIT License + * Permission is hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation files (the ""Software""), to deal in the Software + * without restriction, including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE + * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package com.microsoft.applicationinsights.internal.perfcounter; + +import java.util.HashMap; +import java.util.Map; + +import com.google.common.base.Preconditions; +import com.microsoft.applicationinsights.TelemetryClient; +import com.microsoft.applicationinsights.internal.system.SystemInformation; +import com.microsoft.applicationinsights.telemetry.MetricTelemetry; + +import com.google.common.base.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Built-in Windows performance counters that are sent as {@link com.microsoft.applicationinsights.telemetry.MetricTelemetry} + * + * Created by gupele on 3/30/2015. + */ +public final class WindowsPerformanceCounterAsPC extends AbstractWindowsPerformanceCounter { + + private static final Logger logger = LoggerFactory.getLogger(WindowsPerformanceCounterAsPC.class); + + private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "WindowsPerformanceCounterAsPC"; + + // Performance counter key and its metric name that is relevant when sending. + private final HashMap pcs = new HashMap(); + + /** + * Registers the 'built-in' Windows performance counters that are not fetched from the JVM JMX. + * + * @throws java.lang.Throwable The constructor might throw an Error if the JniPCConnector is not able to properly + * connect to the native code. or Exception if the constructor is not called under Windows OS. + */ + public WindowsPerformanceCounterAsPC() throws Throwable { + Preconditions.checkState(SystemInformation.INSTANCE.isWindows(), "Must be used under Windows OS."); + + register(Constants.TOTAL_CPU_PC_CATEGORY_NAME, Constants.CPU_PC_COUNTER_NAME, Constants.INSTANCE_NAME_TOTAL, Constants.TOTAL_CPU_PC_METRIC_NAME + " FROM JNI"); + register(Constants.PROCESS_CATEGORY, Constants.PROCESS_IO_PC_COUNTER_NAME, JniPCConnector.translateInstanceName(JniPCConnector.PROCESS_SELF_INSTANCE_NAME), + Constants.PROCESS_IO_PC_METRIC_NAME + " FROM JNI"); + + if (pcs.isEmpty()) { + // Failed to register, the performance counter is not needed. + throw new Exception("Failed to register all built-in Windows performance counters."); + } + } + + @Override + public void report(TelemetryClient telemetryClient) { + for (Map.Entry entry : pcs.entrySet()) { + try { + double value = JniPCConnector.getValueOfPerformanceCounter(entry.getKey()); + if (value < 0) { + reportError(value, entry.getValue()); + } else { + send(telemetryClient, value, entry.getValue()); + logger.trace("Sent performance counter for '{}': '{}'", entry.getValue(), value); + } + } catch (ThreadDeath td) { + throw td; + } catch (Throwable e) { + try { + if (logger.isErrorEnabled()) { + logger.error("Failed to send performance counter for '{}'", entry.getValue(), e); + } + } catch (ThreadDeath td) { + throw td; + } catch (Throwable t2) { + // chomp + } + } + } + } + + @Override + public String getId() { + return ID; + } + + private void send(TelemetryClient telemetryClient, double value, String metricName) { + MetricTelemetry telemetry = new MetricTelemetry(metricName, value); + telemetryClient.track(telemetry); + } + + /** + * The method will use the {@link com.microsoft.applicationinsights.internal.perfcounter.JniPCConnector} to register a performance counter. + * The method might throw an Error if the JniPCConnector is not able to properly connect to the native code. + * @param category The category + * @param counter The counter + * @param instance The instnace + */ + private void register(String category, String counter, String instance, String metricName) { + String key = JniPCConnector.addPerformanceCounter(category, counter, instance); + if (!Strings.isNullOrEmpty(key)) { + try { + pcs.put(key, metricName); + } catch (ThreadDeath td) { + throw td; + } catch (Throwable e) { + try { + if (logger.isErrorEnabled()) { + logger.error("Exception while registering windows performance counter as PC", e); + } + } catch (ThreadDeath td) { + throw td; + } catch (Throwable t2) { + // chomp + } + } + } + } +} \ No newline at end of file From 1faefe373e83ab57380346baf97b8ca6c6bf8b95 Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Tue, 9 Feb 2021 15:26:06 -0800 Subject: [PATCH 03/16] Address comments --- .../perfcounter/OshiPerformanceCounter.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java index 73225aa58dc..6c5d66da817 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -35,9 +35,18 @@ public class OshiPerformanceCounter implements PerformanceCounter { private static final Logger logger = LoggerFactory.getLogger(OshiPerformanceCounter.class); private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "OshiPerformanceCounter"; - private final static double NANOS_IN_SECOND = 1000000000.0; + private final static double NANOS_IN_SECOND = 1_000_000_000; private long lastCollectionInNanos = -1; private double prevProcessIO; + private HardwareAbstractionLayer hal; + private OSProcess processInfo; + + public OshiPerformanceCounter() { + SystemInfo systemInfo = new SystemInfo(); + hal = systemInfo.getHardware(); + OperatingSystem osInfo = systemInfo.getOperatingSystem(); + processInfo = osInfo.getProcess(osInfo.getProcessId()); + } @Override public String getId() { return ID; @@ -45,12 +54,6 @@ public class OshiPerformanceCounter implements PerformanceCounter { @Override public void report(TelemetryClient telemetryClient) { long currentCollectionInNanos = System.nanoTime(); - - SystemInfo systemInfo = new SystemInfo(); - HardwareAbstractionLayer hal = systemInfo.getHardware(); - OperatingSystem osInfo = systemInfo.getOperatingSystem(); - OSProcess processInfo = osInfo.getProcess(osInfo.getProcessId()); - double currentProcessIO = 0.0; // system.disk.io @@ -61,7 +64,6 @@ public class OshiPerformanceCounter implements PerformanceCounter { if (lastCollectionInNanos != -1) { double timeElapsedInSeconds = ((double)(currentCollectionInNanos - lastCollectionInNanos)) / NANOS_IN_SECOND; double value = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; - prevProcessIO = currentProcessIO; send(telemetryClient, value, Constants.PROCESS_IO_PC_METRIC_NAME); logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, value); } @@ -71,6 +73,7 @@ public class OshiPerformanceCounter implements PerformanceCounter { // runtime.java.cpu_time processInfo.updateAttributes(); + // getUserTime() and getKernelTime() return the number of milliseconds the process has executed in user mode long totalProcessorTime = (long) ((processInfo.getUserTime() + processInfo.getKernelTime()) * 0.001); send(telemetryClient, totalProcessorTime, Constants.TOTAL_CPU_PC_METRIC_NAME); logger.trace("Sent performance counter for '{}': '{}'", Constants.TOTAL_CPU_PC_METRIC_NAME, totalProcessorTime); From 1932e34b33fdff34b9304b94c9411c71694cba7b Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Tue, 9 Feb 2021 17:40:12 -0800 Subject: [PATCH 04/16] Use process io instead of disk.io --- .../internal/perfcounter/OshiPerformanceCounter.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java index 6c5d66da817..3a8e3ffd194 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -56,10 +56,8 @@ public OshiPerformanceCounter() { long currentCollectionInNanos = System.nanoTime(); double currentProcessIO = 0.0; - // system.disk.io - for (HWDiskStore diskStore : hal.getDiskStores()) { - currentProcessIO += (double) (diskStore.getReadBytes() + diskStore.getWriteBytes()); - } + // process io + currentProcessIO += (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); if (lastCollectionInNanos != -1) { double timeElapsedInSeconds = ((double)(currentCollectionInNanos - lastCollectionInNanos)) / NANOS_IN_SECOND; From 90bdbaf3c14ab2d96b8969139f31de8952164223 Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Wed, 10 Feb 2021 11:28:04 -0800 Subject: [PATCH 05/16] Address feedback --- .../perfcounter/OshiPerformanceCounter.java | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java index 3a8e3ffd194..1a0ac19b22b 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -26,8 +26,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import oshi.SystemInfo; -import oshi.hardware.HWDiskStore; -import oshi.hardware.HardwareAbstractionLayer; import oshi.software.os.OSProcess; import oshi.software.os.OperatingSystem; @@ -36,14 +34,12 @@ public class OshiPerformanceCounter implements PerformanceCounter { private static final Logger logger = LoggerFactory.getLogger(OshiPerformanceCounter.class); private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "OshiPerformanceCounter"; private final static double NANOS_IN_SECOND = 1_000_000_000; - private long lastCollectionInNanos = -1; + private long prevCollectionInNanos = -1; private double prevProcessIO; - private HardwareAbstractionLayer hal; private OSProcess processInfo; public OshiPerformanceCounter() { SystemInfo systemInfo = new SystemInfo(); - hal = systemInfo.getHardware(); OperatingSystem osInfo = systemInfo.getOperatingSystem(); processInfo = osInfo.getProcess(osInfo.getProcessId()); } @@ -53,24 +49,23 @@ public OshiPerformanceCounter() { } @Override public void report(TelemetryClient telemetryClient) { + processInfo.updateAttributes(); + long currentCollectionInNanos = System.nanoTime(); - double currentProcessIO = 0.0; + double currentProcessIO = 0; // process io currentProcessIO += (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); - - if (lastCollectionInNanos != -1) { - double timeElapsedInSeconds = ((double)(currentCollectionInNanos - lastCollectionInNanos)) / NANOS_IN_SECOND; + if (prevCollectionInNanos != -1) { + double timeElapsedInSeconds = (currentCollectionInNanos - prevCollectionInNanos) / NANOS_IN_SECOND; double value = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; send(telemetryClient, value, Constants.PROCESS_IO_PC_METRIC_NAME); logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, value); } prevProcessIO = currentProcessIO; - lastCollectionInNanos = currentCollectionInNanos; + prevCollectionInNanos = currentCollectionInNanos; - // runtime.java.cpu_time - processInfo.updateAttributes(); // getUserTime() and getKernelTime() return the number of milliseconds the process has executed in user mode long totalProcessorTime = (long) ((processInfo.getUserTime() + processInfo.getKernelTime()) * 0.001); send(telemetryClient, totalProcessorTime, Constants.TOTAL_CPU_PC_METRIC_NAME); From f868d294694f1555eeb64efc856963ac88382d70 Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Wed, 10 Feb 2021 12:23:11 -0800 Subject: [PATCH 06/16] Use milliseconds to track elapsed seconds instead of nanoSeconds, which might end up negative values --- .../internal/perfcounter/OshiPerformanceCounter.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java index 1a0ac19b22b..49924f63e9a 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -33,8 +33,8 @@ public class OshiPerformanceCounter implements PerformanceCounter { private static final Logger logger = LoggerFactory.getLogger(OshiPerformanceCounter.class); private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "OshiPerformanceCounter"; - private final static double NANOS_IN_SECOND = 1_000_000_000; - private long prevCollectionInNanos = -1; + private final static double MILLIS_IN_SECOND = 1000; + private long prevCollectionInMillis = -1; private double prevProcessIO; private OSProcess processInfo; @@ -51,20 +51,20 @@ public OshiPerformanceCounter() { @Override public void report(TelemetryClient telemetryClient) { processInfo.updateAttributes(); - long currentCollectionInNanos = System.nanoTime(); + long currentCollectionInMillis = System.currentTimeMillis(); double currentProcessIO = 0; // process io currentProcessIO += (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); - if (prevCollectionInNanos != -1) { - double timeElapsedInSeconds = (currentCollectionInNanos - prevCollectionInNanos) / NANOS_IN_SECOND; + if (prevCollectionInMillis != -1) { + double timeElapsedInSeconds = (currentCollectionInMillis - prevCollectionInMillis) / MILLIS_IN_SECOND; double value = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; send(telemetryClient, value, Constants.PROCESS_IO_PC_METRIC_NAME); logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, value); } prevProcessIO = currentProcessIO; - prevCollectionInNanos = currentCollectionInNanos; + prevCollectionInMillis = currentCollectionInMillis; // getUserTime() and getKernelTime() return the number of milliseconds the process has executed in user mode long totalProcessorTime = (long) ((processInfo.getUserTime() + processInfo.getKernelTime()) * 0.001); From 0a98c050e3aa79b0ba0e029b345623b3dea96a11 Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Wed, 10 Feb 2021 17:47:55 -0800 Subject: [PATCH 07/16] Fix total CPU processor time big diff from JNI --- .../perfcounter/OshiPerformanceCounter.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java index 49924f63e9a..46a3a4288af 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -37,6 +37,7 @@ public class OshiPerformanceCounter implements PerformanceCounter { private long prevCollectionInMillis = -1; private double prevProcessIO; private OSProcess processInfo; + private double prevTotalProcessorTime; public OshiPerformanceCounter() { SystemInfo systemInfo = new SystemInfo(); @@ -52,24 +53,22 @@ public OshiPerformanceCounter() { processInfo.updateAttributes(); long currentCollectionInMillis = System.currentTimeMillis(); - double currentProcessIO = 0; - - // process io - currentProcessIO += (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); + double currentProcessIO = (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); + double currentTotalProcessorTime = processInfo.getUserTime() + processInfo.getKernelTime(); if (prevCollectionInMillis != -1) { double timeElapsedInSeconds = (currentCollectionInMillis - prevCollectionInMillis) / MILLIS_IN_SECOND; - double value = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; - send(telemetryClient, value, Constants.PROCESS_IO_PC_METRIC_NAME); - logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, value); + double processIo = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; + send(telemetryClient, processIo, Constants.PROCESS_IO_PC_METRIC_NAME); + logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, processIo); + + double processorTime = (currentTotalProcessorTime - prevTotalProcessorTime) / timeElapsedInSeconds; + send(telemetryClient, processorTime, Constants.TOTAL_CPU_PC_METRIC_NAME); + logger.trace("Sent performance counter for '{}': '{}'", Constants.TOTAL_CPU_PC_METRIC_NAME, processorTime); } prevProcessIO = currentProcessIO; + prevTotalProcessorTime = currentTotalProcessorTime; prevCollectionInMillis = currentCollectionInMillis; - - // getUserTime() and getKernelTime() return the number of milliseconds the process has executed in user mode - long totalProcessorTime = (long) ((processInfo.getUserTime() + processInfo.getKernelTime()) * 0.001); - send(telemetryClient, totalProcessorTime, Constants.TOTAL_CPU_PC_METRIC_NAME); - logger.trace("Sent performance counter for '{}': '{}'", Constants.TOTAL_CPU_PC_METRIC_NAME, totalProcessorTime); } private void send(TelemetryClient telemetryClient, double value, String metricName) { From 8ff4b62aa0297df0c0da3e8b3ca82d922c450944 Mon Sep 17 00:00:00 2001 From: Helen Yang Date: Wed, 17 Feb 2021 11:57:57 -0800 Subject: [PATCH 08/16] Compute perf counter values during class startup --- .../perfcounter/OshiPerformanceCounter.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java index 46a3a4288af..3771dd8a722 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -36,13 +36,22 @@ public class OshiPerformanceCounter implements PerformanceCounter { private final static double MILLIS_IN_SECOND = 1000; private long prevCollectionInMillis = -1; private double prevProcessIO; + private double currentProcessIO; private OSProcess processInfo; private double prevTotalProcessorTime; + private double currentTotalProcessorTime; public OshiPerformanceCounter() { SystemInfo systemInfo = new SystemInfo(); OperatingSystem osInfo = systemInfo.getOperatingSystem(); processInfo = osInfo.getProcess(osInfo.getProcessId()); + processInfo.updateAttributes(); + + currentProcessIO = (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); + prevProcessIO = currentProcessIO; + + currentTotalProcessorTime = processInfo.getUserTime() + processInfo.getKernelTime(); + prevTotalProcessorTime = currentTotalProcessorTime; } @Override public String getId() { @@ -53,8 +62,8 @@ public OshiPerformanceCounter() { processInfo.updateAttributes(); long currentCollectionInMillis = System.currentTimeMillis(); - double currentProcessIO = (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); - double currentTotalProcessorTime = processInfo.getUserTime() + processInfo.getKernelTime(); + currentProcessIO = (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); + currentTotalProcessorTime = processInfo.getUserTime() + processInfo.getKernelTime(); if (prevCollectionInMillis != -1) { double timeElapsedInSeconds = (currentCollectionInMillis - prevCollectionInMillis) / MILLIS_IN_SECOND; double processIo = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; From 8b21bf4a32c110bda1a879874bd65498a491532d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 18 Mar 2021 21:53:19 -0700 Subject: [PATCH 09/16] Update oshi version --- core/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/build.gradle b/core/build.gradle index 26a7a03d757..14f10092caa 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -85,7 +85,7 @@ dependencies { compile ([group: 'com.google.code.gson', name: 'gson', version: '2.8.2']) // update transitive dependency version compile ([group: 'com.google.guava', name: 'guava', version: '27.1-android']) - compile ([group: 'com.github.oshi', name:'oshi-core',version:'5.3.1']) + compile ([group: 'com.github.oshi', name:'oshi-core',version:'5.6.0']) compile 'org.slf4j:slf4j-api:1.7.26' testCompile group: 'org.hamcrest', name:'hamcrest-core', version:'1.3' testCompile group: 'org.hamcrest', name:'hamcrest-library', version:'1.3' From 341d74ef8638bbe240fdc5e14dded651d0f85952 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 19 Mar 2021 17:47:01 -0700 Subject: [PATCH 10/16] Use system cpu --- .../perfcounter/OshiPerformanceCounter.java | 86 ++++++++++++------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java index 3771dd8a722..47152a8806a 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/OshiPerformanceCounter.java @@ -26,6 +26,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.CentralProcessor.TickType; import oshi.software.os.OSProcess; import oshi.software.os.OperatingSystem; @@ -33,51 +35,71 @@ public class OshiPerformanceCounter implements PerformanceCounter { private static final Logger logger = LoggerFactory.getLogger(OshiPerformanceCounter.class); private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "OshiPerformanceCounter"; - private final static double MILLIS_IN_SECOND = 1000; - private long prevCollectionInMillis = -1; - private double prevProcessIO; - private double currentProcessIO; - private OSProcess processInfo; - private double prevTotalProcessorTime; - private double currentTotalProcessorTime; + + private static final double MILLIS_IN_SECOND = 1000; + + private long prevCollectionTimeMillis; + private long prevProcessBytes; + private long prevTotalProcessorMillis; + + private final OSProcess processInfo; + private final CentralProcessor processor; public OshiPerformanceCounter() { SystemInfo systemInfo = new SystemInfo(); OperatingSystem osInfo = systemInfo.getOperatingSystem(); processInfo = osInfo.getProcess(osInfo.getProcessId()); - processInfo.updateAttributes(); + processor = systemInfo.getHardware().getProcessor(); - currentProcessIO = (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); - prevProcessIO = currentProcessIO; - - currentTotalProcessorTime = processInfo.getUserTime() + processInfo.getKernelTime(); - prevTotalProcessorTime = currentTotalProcessorTime; + // grab values early, so that we will have something to report the first time report() is called + updateAttributes(processInfo); + prevCollectionTimeMillis = System.currentTimeMillis(); + prevProcessBytes = getProcessBytes(processInfo); + prevTotalProcessorMillis = getTotalProcessorMillis(processor); } - @Override public String getId() { + @Override + public String getId() { return ID; } - @Override public void report(TelemetryClient telemetryClient) { - processInfo.updateAttributes(); - - long currentCollectionInMillis = System.currentTimeMillis(); - currentProcessIO = (double) (processInfo.getBytesRead() + processInfo.getBytesWritten()); - currentTotalProcessorTime = processInfo.getUserTime() + processInfo.getKernelTime(); - if (prevCollectionInMillis != -1) { - double timeElapsedInSeconds = (currentCollectionInMillis - prevCollectionInMillis) / MILLIS_IN_SECOND; - double processIo = (currentProcessIO - prevProcessIO) / timeElapsedInSeconds; - send(telemetryClient, processIo, Constants.PROCESS_IO_PC_METRIC_NAME); - logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, processIo); - - double processorTime = (currentTotalProcessorTime - prevTotalProcessorTime) / timeElapsedInSeconds; - send(telemetryClient, processorTime, Constants.TOTAL_CPU_PC_METRIC_NAME); - logger.trace("Sent performance counter for '{}': '{}'", Constants.TOTAL_CPU_PC_METRIC_NAME, processorTime); + @Override + public void report(TelemetryClient telemetryClient) { + long currCollectionTimeMillis = System.currentTimeMillis(); + updateAttributes(processInfo); + long currProcessBytes = getProcessBytes(processInfo); + long currTotalProcessorMillis = getTotalProcessorMillis(processor); + + double elapsedMillis = currCollectionTimeMillis - prevCollectionTimeMillis; + double elapsedSeconds = elapsedMillis / MILLIS_IN_SECOND; + double processBytes = (currProcessBytes - prevProcessBytes) / elapsedSeconds; + send(telemetryClient, processBytes, Constants.PROCESS_IO_PC_METRIC_NAME); + logger.trace("Sent performance counter for '{}': '{}'", Constants.PROCESS_IO_PC_METRIC_NAME, processBytes); + + double processorLoad = (currTotalProcessorMillis - prevTotalProcessorMillis) / (elapsedMillis * processor.getLogicalProcessorCount()); + double processorPercentage = 100 * processorLoad; + send(telemetryClient, processorPercentage, Constants.TOTAL_CPU_PC_METRIC_NAME); + logger.trace("Sent performance counter for '{}': '{}'", Constants.TOTAL_CPU_PC_METRIC_NAME, processorPercentage); + + prevCollectionTimeMillis = currCollectionTimeMillis; + prevProcessBytes = currProcessBytes; + prevTotalProcessorMillis = currTotalProcessorMillis; + } + + private static void updateAttributes(OSProcess processInfo) { + if (!processInfo.updateAttributes()) { + logger.debug("could not update process attributes"); } + } + + // must call updateAttributes on processInfo before calling this method + private static long getProcessBytes(OSProcess processInfo) { + return processInfo.getBytesRead() + processInfo.getBytesWritten(); + } - prevProcessIO = currentProcessIO; - prevTotalProcessorTime = currentTotalProcessorTime; - prevCollectionInMillis = currentCollectionInMillis; + private static long getTotalProcessorMillis(CentralProcessor processor) { + long[] systemCpuLoadTicks = processor.getSystemCpuLoadTicks(); + return systemCpuLoadTicks[TickType.USER.getIndex()] + systemCpuLoadTicks[TickType.SYSTEM.getIndex()]; } private void send(TelemetryClient telemetryClient, double value, String metricName) { From fe09f6783d8e42dd133ec1e7bdef1d1a7dd47590 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 20 Mar 2021 10:49:35 -0700 Subject: [PATCH 11/16] Remove old windows jni perf counters --- core/build.gradle | 33 -- core/native.gradle | 202 ------------- core/spotbugs.exclude.xml | 10 - .../internal/config/ReflectionUtils.java | 2 - .../AbstractWindowsPerformanceCounter.java | 33 -- .../internal/perfcounter/JniPCConnector.java | 286 ------------------ ...cessBuiltInPerformanceCountersFactory.java | 6 +- .../ProcessPerformanceCountersModule.java | 37 +-- .../WindowsPerformanceCounterAsPC.java | 133 -------- core/src/windows/cpp/CppPerfCounters.cpp | 284 ----------------- core/src/windows/cpp/CppPerfCounters.h | 52 ---- core/src/windows/cpp/CppPerfCounters.vcxproj | 175 ----------- .../cpp/CppPerfCounters.vcxproj.filters | 47 --- .../diagnostics/etw/DllFileUtils.java | 2 - 14 files changed, 4 insertions(+), 1298 deletions(-) delete mode 100644 core/native.gradle delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractWindowsPerformanceCounter.java delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/JniPCConnector.java delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java delete mode 100644 core/src/windows/cpp/CppPerfCounters.cpp delete mode 100644 core/src/windows/cpp/CppPerfCounters.h delete mode 100644 core/src/windows/cpp/CppPerfCounters.vcxproj delete mode 100644 core/src/windows/cpp/CppPerfCounters.vcxproj.filters diff --git a/core/build.gradle b/core/build.gradle index 14f10092caa..ea51032acf7 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -32,39 +32,6 @@ sourceSets { } } -clean { - delete "${System.properties['java.io.tmpdir']}/AISDK/native" // see JniPCConnector.java for jni directory -} - -// CURRENTLY the DLL being built on CI is not working, leading to this error on startup: -// -// ERROR c.m.a.i.perfcounter.JniPCConnector - Unexpected error initializing JNI Performance Counter library. Windows performance counters will not be used -// java.lang.UnsatisfiedLinkError: C:\Users\trstalna\AppData\Local\Temp\AISDK\native\3.0.0-PREVIEW.7-SNAPSHOT\applicationinsights-core-native-win64.dll: Can't find dependent libraries -// -// and native windows perf counters do not get collected -// -// so instead of building the DLLs, we are currently just copying the previously built DLLs from 2.6.2 which work fine -// (see copyTheDLL task below) - -/* -import org.apache.tools.ant.taskdefs.condition.Os - -boolean skipWinNative = (System.properties['skipWinNative'] ?: 'false').toBoolean() -if (skipWinNative) { - logger.warn 'Windows native components will not be built: skipWinNative=true' - if (isRelease) { - logger.error 'skipWinNative=true and isRelease=true' - throw new GradleException('Cannot use skipWinNative=true and isRelease=true') - } -} else { - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - apply from: "native.gradle" - } else { - logger.warn("Native binaries build is only supported on Windows systems; native components will not be built.") - } -} -*/ - import com.microsoft.applicationinsights.build.tasks.PropsFileGen archivesBaseName = 'applicationinsights-core' diff --git a/core/native.gradle b/core/native.gradle deleted file mode 100644 index f94b155765a..00000000000 --- a/core/native.gradle +++ /dev/null @@ -1,202 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -apply plugin: 'cpp' -apply plugin: 'idea' - -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath group: 'commons-io', name: 'commons-io', version: '2.6' - } -} - -import org.apache.commons.io.FilenameUtils - -def javaIncludeDir = new File(System.env.'JAVA_HOME', "include") -def programFilesX86 = System.env.'ProgramFiles(x86)' ?: 'C:\\Program Files (x86)' - -def winSdkDir = "$programFilesX86\\Windows Kits\\8.1" -if (System.env.APPINSIGHTS_WIN_SDK_PATH) { - winSdkDir = System.env.APPINSIGHTS_WIN_SDK_PATH - println "Using custom Windows SDK path: $winSdkDir" -} -def vsToolsDir = "$programFilesX86\\Microsoft Visual Studio 14.0" -if (System.env.APPINSIGHTS_VS_PATH) { - vsToolsDir = System.env.APPINSIGHTS_VS_PATH - println "Using custom Visual Studio Tools path: $vsToolsDir" -} - -idea { - module { - sourceDirs += file("$projectDir/src/windows/cpp") - } -} - -// region Native binary definition and configuration -model { - toolChains { - visualCpp(VisualCpp) { - windowsSdkDir winSdkDir - installDir vsToolsDir - } - } - buildTypes { - release - debug - } - platforms { - x86 { architecture "x86" } - x64 { architecture "amd64" } - } - - components { - "windows"(NativeLibrarySpec) { - targetPlatform "x86" - targetPlatform "x64" - - baseName = "applicationinsights-core-native-win" - - sources { - cpp { - source { - include "**/*.cpp" - include "**/*.h" - } - } - } - - if ((System.properties["isRelease"] ?: "false").toBoolean()) { - targetBuildTypes "release" - } else { - targetBuildTypes "debug" - } - - binaries.all { - if (delegate instanceof StaticLibraryBinarySpec) { - buildable = false - } else { - assert (delegate instanceof SharedLibraryBinarySpec) - sharedLibraryFile = ReconstructFileName(sharedLibraryFile, buildType, targetPlatform) - - tasks.all { t -> - logger.info "Adding \"processResources\".dependsOn \"$t\" (${t.getClass()})" - processResources.dependsOn t - } - - logger.info "Adding \"$sharedLibraryFile.parentFile\" to sourceSets.main.resources" - sourceSets.main.resources.srcDir sharedLibraryFile.parentFile - - } - if (toolChain in VisualCpp) { - // Visual Studio Compiler Options: https://msdn.microsoft.com/en-us/library/fwkeyyhe.aspx - // Visual Studio Linker Options: https://msdn.microsoft.com/en-us/library/y0zzbyt4.aspx - - // Searches a directory for include files. - cppCompiler.args "/I$javaIncludeDir" - cppCompiler.args "/I$javaIncludeDir\\win32" - - // Produces an output file to run on the common language runtime. - cppCompiler.args "/clr" - - // Sets warning level. - cppCompiler.args "/W3" - - // Catch both asynchronous (structured) and synchronous (C++) exceptions. - cppCompiler.args "/EHa" - - // Compiler macros definition - cppCompiler.define "WIN32" - cppCompiler.define "UNICODE" - cppCompiler.define "_UNICODE" - cppCompiler.define "_WINDLL" - - if (buildType == buildTypes.release) { - cppCompiler.define 'NDEBUG' - - // Use the multithread-specific and DLL-specific version of the run-time library. - cppCompiler.args '/MD' - - // Creates the fastest code in the majority of cases. - cppCompiler.args '/O2' - } else { - cppCompiler.define '_DEBUG' - - // Generates complete debugging information. - cppCompiler.args '/Zi' - - // Creates debugging information. - linker.args '/DEBUG' - - //Disables optimization. - cppCompiler.args "/Od" - - // Use the debug multithread-specific and DLL-specific version of the run-time library. - cppCompiler.args '/MDd' - - cppCompiler.args '/FS' - } - } - } - - } - } -} - -sourceSets { - main { - resources { - exclude "**/*.exp" - exclude "**/*.lib" - exclude "**/*.pdb" - } - } -} - -// This function will reconstruct the file name based on the buildType and targetPlatform -// New file name structure: <32|64>[dbg]. -def ReconstructFileName(File originalFile, BuildType buildType, NativePlatform targetPlatform) { - def originalFileName = originalFile.absolutePath - def filePath = FilenameUtils.getFullPath(originalFileName) - def baseName = FilenameUtils.getBaseName(originalFileName) - def extension = FilenameUtils.getExtension(originalFileName) - - def bitnessPart = "" - switch (targetPlatform.name) { - case "x86" : - bitnessPart = "32" - break; - case "x64" : - bitnessPart = "64" - break; - default: - logger.warn "Unexpected targetPlatform encountered - skipping setting the file name bitness part" - } - - def newName = "$baseName$bitnessPart.$extension" - def newFile = new File(filePath, newName) - logger.info "Reconstructed file name: $originalFile => $newFile" - newFile -} - -// endregion Private Methods diff --git a/core/spotbugs.exclude.xml b/core/spotbugs.exclude.xml index 95df167ea66..3c96c2f2f58 100644 --- a/core/spotbugs.exclude.xml +++ b/core/spotbugs.exclude.xml @@ -132,11 +132,6 @@ - - - - - @@ -162,11 +157,6 @@ - - - - - diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/config/ReflectionUtils.java b/core/src/main/java/com/microsoft/applicationinsights/internal/config/ReflectionUtils.java index e05d081382d..c8ba18427e6 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/config/ReflectionUtils.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/config/ReflectionUtils.java @@ -48,8 +48,6 @@ public final class ReflectionUtils { addClass(com.microsoft.applicationinsights.internal.heartbeat.HeartBeatModule.class); addClass(com.microsoft.applicationinsights.internal.perfcounter.JvmPerformanceCountersModule.class); - addClass(com.microsoft.applicationinsights.internal.perfcounter.ProcessPerformanceCountersModule.class); - addClass(com.microsoft.applicationinsights.extensibility.initializer.SdkVersionContextInitializer.class); } diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractWindowsPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractWindowsPerformanceCounter.java deleted file mode 100644 index 6a0ee3a0752..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractWindowsPerformanceCounter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.microsoft.applicationinsights.internal.perfcounter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by gupele on 4/29/2015. - */ -public abstract class AbstractWindowsPerformanceCounter implements PerformanceCounter { - - private static final Logger logger = LoggerFactory.getLogger(AbstractWindowsPerformanceCounter.class); - - protected void reportError(double value, String displayName) { - if (!logger.isErrorEnabled()) { - return; - } - - if (value == -1) { - logger.error("Native code exception in wrapper while fetching counter value '{}'", displayName); - } else if (value == -4) { - logger.error("Native code exception in internal wrapper while fetching counter value '{}'", displayName); - } else if (value == -2) { - logger.error("Native code exception performance counter '{}' not found", displayName); - } else if (value == -7) { - logger.error("Native code exception while fetching counter value '{}'", displayName); - } else { - logger.error("Native code unknown exception while fetching counter value '{}'", displayName); - } - } - - protected AbstractWindowsPerformanceCounter() { - } -} diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/JniPCConnector.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/JniPCConnector.java deleted file mode 100644 index 33d8330dd46..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/JniPCConnector.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import com.microsoft.applicationinsights.internal.system.SystemInformation; - -import com.microsoft.applicationinsights.internal.util.LocalFileSystemUtils; -import com.microsoft.applicationinsights.internal.util.PropertyHelper; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * This class serves as the connection to the native code that does the work with Windows. - * - * Created by gupele on 3/30/2015. - */ -public final class JniPCConnector { - - private static final Logger logger = LoggerFactory.getLogger(JniPCConnector.class); - - public static final String AI_BASE_FOLDER = "AISDK"; - public static final String AI_NATIVE_FOLDER = "native"; - public static final String PROCESS_SELF_INSTANCE_NAME = "__SELF__"; - - private static final String BITS_MODEL_64 = "64"; - private static final String NATIVE_LIBRARY_64 = "applicationinsights-core-native-win64.dll"; - private static final String NATIVE_LIBRARY_32 = "applicationinsights-core-native-win32.dll"; - - private static String currentInstanceName; - - // Native methods are private and can be accessed through matching public methods in the class. - private native static String getInstanceName(int processId); - - private native static String addCounter(String category, String counter, String instance); - - private native static double getPerformanceCounterValue(String name); - - /** - * This method must be called before any other method. - * All other methods are relevant only if this method was successful. - * - * Note that the method should not throw and should gracefully return the boolean value. - * @return True on success. - */ - public static boolean initialize() { - try { - if (!SystemInformation.INSTANCE.isWindows()) { - logger.error("Jni connector is only used on Windows OS."); - return false; - } - - loadNativeLibrary(); - } catch (ThreadDeath td) { - throw td; - } catch (JNIPerformanceCounterConnectorException e) { - logger.error("Error initializing JNI Performance Counter library. Windows performance counters will not be used.", e); - } catch (Throwable e) { - try { - logger.error("Unexpected error initializing JNI Performance Counter library. Windows performance counters will not be used", e); - - return false; - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t2) { - // chomp - } - } - - return true; - } - - /** - * Adding a performance counter - * @param category The category must be non null non empty value. - * @param counter The counter must be non null non empty value. - * @param instance The instance. - * @return The key for retrieving counter data. - */ - public static String addPerformanceCounter(String category, String counter, String instance) { - if (StringUtils.isEmpty(category)) { - throw new IllegalArgumentException("category must be non-null non empty string."); - } - if (StringUtils.isEmpty(counter)) { - throw new IllegalArgumentException("counter must be non-null non empty string."); - } - - if (logger.isTraceEnabled()) { - logger.trace("Registering performance counter: {} \\ {} [{}]", category, counter, StringUtils.trimToEmpty(instance)); - } - final String s = addCounter(category, counter, instance); - if (StringUtils.isEmpty(s) && logger.isWarnEnabled()) { - logger.warn("Performance coutner registration failed for {} \\ {} [{}]", category, counter, StringUtils.trimToEmpty(instance)); - } - return s; - } - - /** - * Process instance name is only known at runtime, therefore process level performance counters - * should use the 'PROCESS_SELF_INSTANCE_NAME' as the requested process name and then call this - * method to translate that logical name into the actual name that is fetched from the native code. - * @param instanceName The raw instance name - * @return The actual instance name. - * @throws Exception If instanceName equals PROCESS_SELF_INSTANCE_NAME but the actual instance name is unknown. - */ - public static String translateInstanceName(String instanceName) throws Exception { - if (PROCESS_SELF_INSTANCE_NAME.equals(instanceName)) { - if (StringUtils.isEmpty(currentInstanceName)) { - throw new Exception("Cannot translate instance name: Unknown current instance name"); - } - - return currentInstanceName; - } - - return instanceName; - } - - /** - * This method will delegate the call to the native code after the proper sanity checks. - * @param name The logical name of the performance counter as was fetched during the 'addPerformanceCounter' call. - * @return The current value. - */ - public static double getValueOfPerformanceCounter(String name) { - if(StringUtils.isEmpty(name)) { - throw new IllegalArgumentException("name must be non-null non empty value."); - } - - return getPerformanceCounterValue(name); - } - - /** - * Performance Counters identify a process by "Instance Name." - * This will be the executable name without the extension, e.g. a process running java.exe will have an instance name "java". - * If there are multiple instances of the same executable, an additional identifier is appended. By default this looks like "java#1", "java#2". - * For some reason, the instance name can change after the process starts with the default naming scheme. - * - * To workaround this, add a DWORD registry value named 'ProcessNameFormat' set to the value '2' to the key - * 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfProc\Performance'. - * This changes the naming scheme from "java#2" to "java_PID" where PID is the current process id. It also makes the name constant for the life of the process. - * - * @throws NumberFormatException if pid cannot be parsed. - */ - private static void initNativeCode() { - int processId = Integer.parseInt(SystemInformation.INSTANCE.getProcessId()); - - currentInstanceName = getInstanceName(processId); - if (StringUtils.isEmpty(currentInstanceName)) { - logger.error("Failed to fetch current process instance name, process counters for for the process level will not be activated."); - } else { - logger.debug("Java process instance name is set to '{}'", currentInstanceName); - } - } - - /** - * The method will try to extract the dll for the Windows performance counters to a local - * folder and then will try to load it. The method will do all that by doing the following things: - * 1. Find the OS type (64/32) currently supports only 64 bit. - * 2. Will find the path to extract to, which is %temp%/AI_BASE_FOLDER/AI_NATIVE_FOLDER/sdk_version_number - * 3. Find out whether or not the file already exists in that directory - * 4. If the dll is not there, the method will extract it from the jar to that directory - * 5. The method will call System.load to load the dll and by doing so we are ready to use it - * @return true on success, otherwise false - * @throws IOException If there are errors in opening/writing/reading/closing etc. - * Note that the method might throw RuntimeExceptions due to critical issues - */ - private static void loadNativeLibrary() throws JNIPerformanceCounterConnectorException { - final File dllOnDisk; - final String libraryToLoad; - try { - String model = System.getProperty("sun.arch.data.model"); - libraryToLoad = BITS_MODEL_64.equals(model) ? NATIVE_LIBRARY_64 : NATIVE_LIBRARY_32; - - File dllPath = buildDllLocalPath(); - - dllOnDisk = new File(dllPath, libraryToLoad); - - if (!dllOnDisk.exists()) { - extractToLocalFolder(dllOnDisk, libraryToLoad); - } else { - logger.trace("Found existing DLL: {}", dllOnDisk.getAbsolutePath()); - } - } catch (Exception e) { - throw new JNIPerformanceCounterConnectorException("Error extracting DLL to disk", e); - } - - try { - System.load(dllOnDisk.toString()); - } catch (Exception e) { - throw new JNIPerformanceCounterConnectorException("Error loading DLL. Please make sure that Visual C++ 2015 Redistributable is properly installed", e); - } - - try { - initNativeCode(); - } catch (NumberFormatException e) { - throw new JNIPerformanceCounterConnectorException("Could not parse PID as int", e); - } catch (Exception e) { - throw new JNIPerformanceCounterConnectorException("Unexpected error initializing performance counter DLL library", e); - } - - logger.trace("Successfully loaded library '{}'", libraryToLoad); - } - - private static void extractToLocalFolder(File dllOnDisk, String libraryToLoad) throws IOException { - ClassLoader classLoader = JniPCConnector.class.getClassLoader(); - if (classLoader == null) { - classLoader = ClassLoader.getSystemClassLoader(); - } - InputStream in = classLoader.getResourceAsStream(libraryToLoad); - if (in == null) { - throw new RuntimeException("Failed to find '"+libraryToLoad+"' in jar"); - } - - OutputStream out = null; - try { - out = FileUtils.openOutputStream(dllOnDisk); - IOUtils.copy(in, out); - - logger.trace("Successfully extracted '{}' to local folder", libraryToLoad); - } finally { - try { - in.close(); - } catch (IOException e) { - logger.error("Failed to close input stream for dll extraction: {}", e.toString()); - } - if (out != null) { - try { - out.close(); - } catch (IOException e) { - logger.error("Failed to close output stream for dll extraction: {}", e.toString()); - } - } - } - } - - private static File buildDllLocalPath() { - File dllPath = LocalFileSystemUtils.getTempDir(); - - dllPath = new File(dllPath.toString(), AI_BASE_FOLDER); - dllPath = new File(dllPath.toString(), AI_NATIVE_FOLDER); - dllPath = new File(dllPath.toString(), PropertyHelper.getSdkVersionNumber()); - - if (!dllPath.exists()) { - dllPath.mkdirs(); - } - - if (!dllPath.exists() || !dllPath.canRead() || !dllPath.canWrite()) { - throw new RuntimeException("Failed to create a read/write folder for the native dll."); - } - - logger.trace("{} folder exists", dllPath.toString()); - - return dllPath; - } - - private static class JNIPerformanceCounterConnectorException extends Exception { - public JNIPerformanceCounterConnectorException(String s, Throwable throwable) { - super(s, throwable); - } - } -} diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java index 62e906251f4..f5d7d8bf669 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java @@ -104,11 +104,7 @@ private Collection getWindowsPerformanceCounters() { ArrayList performanceCounters = getMutualPerformanceCounters(); try { - OshiPerformanceCounter oshiPerfCounter = new OshiPerformanceCounter(); - performanceCounters.add(oshiPerfCounter); - - WindowsPerformanceCounterAsPC wpc = new WindowsPerformanceCounterAsPC(); - performanceCounters.add(wpc); + performanceCounters.add(new OshiPerformanceCounter()); } catch (ThreadDeath td) { throw td; } catch (Throwable e) { diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessPerformanceCountersModule.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessPerformanceCountersModule.java index 83cee4c7ddd..97281f3841d 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessPerformanceCountersModule.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessPerformanceCountersModule.java @@ -21,45 +21,14 @@ package com.microsoft.applicationinsights.internal.perfcounter; -import com.microsoft.applicationinsights.internal.config.PerformanceCountersXmlElement; -import com.microsoft.applicationinsights.internal.system.SystemInformation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * The class will be used when the SDK needs to add the 'built-in' performance counters. * * Created by gupele on 3/3/2015. */ -public final class ProcessPerformanceCountersModule extends AbstractPerformanceCounterModule implements PerformanceCounterConfigurationAware { - - private static final Logger logger = LoggerFactory.getLogger(ProcessPerformanceCountersModule.class); - - public ProcessPerformanceCountersModule() throws Exception { - this(new ProcessBuiltInPerformanceCountersFactory()); - } - - public ProcessPerformanceCountersModule(PerformanceCountersFactory factory) { - super(factory); - } - - /** - * This method checks for Windows performance counters from the configuration. - * The method will work only if the process is activated under Windows OS. The method will initialize - * the connection to the native code using {@link com.microsoft.applicationinsights.internal.perfcounter.JniPCConnector} - * and then will go through the requested performance counters, normalize them, and will hand them to the factory. - * @param configuration The configuration of that section - */ - @Override - public void addConfigurationData(PerformanceCountersXmlElement configuration) { - if (!SystemInformation.INSTANCE.isWindows()) { - logger.trace("Windows performance counters are not relevant on this OS."); - return; - } +public final class ProcessPerformanceCountersModule extends AbstractPerformanceCounterModule { - if (!JniPCConnector.initialize()) { - logger.error("Failed to initialize JNI connection."); - return; - } + public ProcessPerformanceCountersModule() { + super(new ProcessBuiltInPerformanceCountersFactory()); } } diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java deleted file mode 100644 index 23c8e23fc04..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/WindowsPerformanceCounterAsPC.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import java.util.HashMap; -import java.util.Map; - -import com.google.common.base.Preconditions; -import com.microsoft.applicationinsights.TelemetryClient; -import com.microsoft.applicationinsights.internal.system.SystemInformation; -import com.microsoft.applicationinsights.telemetry.MetricTelemetry; - -import com.google.common.base.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Built-in Windows performance counters that are sent as {@link com.microsoft.applicationinsights.telemetry.MetricTelemetry} - * - * Created by gupele on 3/30/2015. - */ -public final class WindowsPerformanceCounterAsPC extends AbstractWindowsPerformanceCounter { - - private static final Logger logger = LoggerFactory.getLogger(WindowsPerformanceCounterAsPC.class); - - private static final String ID = Constants.PERFORMANCE_COUNTER_PREFIX + "WindowsPerformanceCounterAsPC"; - - // Performance counter key and its metric name that is relevant when sending. - private final HashMap pcs = new HashMap<>(); - - /** - * Registers the 'built-in' Windows performance counters that are not fetched from the JVM JMX. - * - * @throws java.lang.Throwable The constructor might throw an Error if the JniPCConnector is not able to properly - * connect to the native code. or Exception if the constructor is not called under Windows OS. - */ - public WindowsPerformanceCounterAsPC() throws Throwable { - Preconditions.checkState(SystemInformation.INSTANCE.isWindows(), "Must be used under Windows OS."); - - register(Constants.TOTAL_CPU_PC_CATEGORY_NAME, Constants.CPU_PC_COUNTER_NAME, Constants.INSTANCE_NAME_TOTAL, Constants.TOTAL_CPU_PC_METRIC_NAME + " FROM JNI"); - register(Constants.PROCESS_CATEGORY, Constants.PROCESS_IO_PC_COUNTER_NAME, JniPCConnector.translateInstanceName(JniPCConnector.PROCESS_SELF_INSTANCE_NAME), - Constants.PROCESS_IO_PC_METRIC_NAME + " FROM JNI"); - - if (pcs.isEmpty()) { - // Failed to register, the performance counter is not needed. - throw new Exception("Failed to register all built-in Windows performance counters."); - } - } - - @Override - public void report(TelemetryClient telemetryClient) { - for (Map.Entry entry : pcs.entrySet()) { - try { - double value = JniPCConnector.getValueOfPerformanceCounter(entry.getKey()); - if (value < 0) { - reportError(value, entry.getValue()); - } else { - send(telemetryClient, value, entry.getValue()); - logger.trace("Sent performance counter for '{}': '{}'", entry.getValue(), value); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable e) { - try { - if (logger.isErrorEnabled()) { - logger.error("Failed to send performance counter for '{}'", entry.getValue(), e); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t2) { - // chomp - } - } - } - } - - @Override - public String getId() { - return ID; - } - - private void send(TelemetryClient telemetryClient, double value, String metricName) { - MetricTelemetry telemetry = new MetricTelemetry(metricName, value); - telemetryClient.track(telemetry); - } - - /** - * The method will use the {@link com.microsoft.applicationinsights.internal.perfcounter.JniPCConnector} to register a performance counter. - * The method might throw an Error if the JniPCConnector is not able to properly connect to the native code. - * @param category The category - * @param counter The counter - * @param instance The instnace - */ - private void register(String category, String counter, String instance, String metricName) { - String key = JniPCConnector.addPerformanceCounter(category, counter, instance); - if (!Strings.isNullOrEmpty(key)) { - try { - pcs.put(key, metricName); - } catch (ThreadDeath td) { - throw td; - } catch (Throwable e) { - try { - if (logger.isErrorEnabled()) { - logger.error("Exception while registering windows performance counter as PC", e); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t2) { - // chomp - } - } - } - } -} \ No newline at end of file diff --git a/core/src/windows/cpp/CppPerfCounters.cpp b/core/src/windows/cpp/CppPerfCounters.cpp deleted file mode 100644 index e5651d588ce..00000000000 --- a/core/src/windows/cpp/CppPerfCounters.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -// This is the main DLL file. - -#include "CppPerfCounters.h" - -#include - -#using -#using -#using -#using - -using System::Text::Encoding; -using namespace System::Reflection; -using namespace System; -using namespace System::IO; -using namespace System::Collections::Generic; -using namespace System::Diagnostics; - -using System::Runtime::InteropServices::Marshal; -using namespace Microsoft; - -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// -[assembly:AssemblyTitleAttribute(L"Microsoft.ApplicationInsights.JNI.PerformanceCounters")]; -[assembly:AssemblyDescriptionAttribute(L"Microsoft Application Insights Java SDK Windows Performance Counters Manager. This package provides JNI methods for collecting Windows performance counters via the Java SDK.")]; -[assembly:AssemblyConfigurationAttribute(L"Retail")]; -[assembly:AssemblyCompanyAttribute(L"Microsoft")]; -[assembly:AssemblyProductAttribute(L"Microsoft Application Insights Java SDK")]; -[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2019")]; -[assembly:AssemblyTrademarkAttribute(L"Microsoft Application Insights Java SDK")]; -[assembly:AssemblyCultureAttribute(L"")]; - -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the value or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly:AssemblyFileVersion("1.0.0.0")]; -[assembly:AssemblyVersionAttribute("1.0.0.0")]; - -[assembly:CLSCompliantAttribute(true)]; - -static const double EXCEPTION_IN_GET_PERF_COUNTER_WRAPPER_FUNCTION_EXCEPTION = -1; -static const double EXCEPTION_WHILE_FETCHING_PERF_COUNTER_VALUE = -7; -static const double EXCEPTION_IN_GET_PERF_COUNTER_INTERNAL_WRAPPER_FUNCTION_EXCEPTION = -4; -static const double PERF_COUNTER_WAS_NOT_FOUND = -2; - -ref class PerfCountersUtils -{ -private: - static Dictionary^ pcDictionary = gcnew Dictionary; - -public: - static String^ getInstanceName(long processId) - { - String^ instanceName = GetInstanceNameForProcessId(processId); - if (instanceName == nullptr) - { - return nullptr; - } - - return instanceName; - } - - static String^ AddProcessPerformanceCounter( - String^ performanceCounterCategoryName, - String^ performanceCounterCounterName, - String^ performanceCounterInstanceName) - { - String^ key = performanceCounterCategoryName + performanceCounterCounterName + performanceCounterInstanceName; - if (pcDictionary->ContainsKey(key)) - { - return key; - } - - PerformanceCounter^ pc = gcnew PerformanceCounter(performanceCounterCategoryName, performanceCounterCounterName, performanceCounterInstanceName); - pcDictionary->Add(key, pc); - return key; - } - - static double GetProcessPerformanceCounterValue(String^ performanceCounterName) - { - PerformanceCounter^ pc; - bool found = pcDictionary->TryGetValue(performanceCounterName, pc); - if (!found) - { - return PERF_COUNTER_WAS_NOT_FOUND; - } - - try - { - double value = pc->NextValue(); - return value; - } - catch (...) - { - return EXCEPTION_WHILE_FETCHING_PERF_COUNTER_VALUE; - } - } - -private: - static String^ GetInstanceNameForProcessId(long processId) - { - Process^ process = Process::GetProcessById(processId); - String^ processName = Path::GetFileNameWithoutExtension(process->ProcessName); - - PerformanceCounterCategory^ cat = gcnew PerformanceCounterCategory("Process"); - array^ instances = cat->GetInstanceNames(); - - for each(String^ instance in instances) - { - if (!instance->StartsWith(processName)) - { - continue; - } - - PerformanceCounter^ cnt = gcnew PerformanceCounter("Process", "ID Process", instance, true); - int val = (int)cnt->RawValue; - delete cnt; - if (val == processId) - { - return instance; - } - } - - return nullptr; - } -}; - -String^ toString(const char*chars) -{ - int len = (int)strlen(chars); - array^ a = gcnew array(len); - int i = 0; - while (i < len) - { - a[i] = chars[i]; - ++i; - } - - return Encoding::UTF8->GetString(a); -} - -String^ getInstanceName(long processId) { - return PerfCountersUtils::getInstanceName(processId); -} - -String^ addProcessCounter(const char *category, const char *name, const char *instance) -{ - try - { - return PerfCountersUtils::AddProcessPerformanceCounter(toString(category), toString(name), toString(instance)); - } - catch (...) - { - return nullptr; - } -} - -double getPerfCounterValue(const char *name) { - try - { - return PerfCountersUtils::GetProcessPerformanceCounterValue(toString(name)); - } - catch (...) - { - return EXCEPTION_IN_GET_PERF_COUNTER_INTERNAL_WRAPPER_FUNCTION_EXCEPTION; - } -} - -void MarshalString(String ^s, std::string& ostr) { - const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer(); - ostr = chars; - Marshal::FreeHGlobal(IntPtr((void*)chars)); -} - -JNIEXPORT jstring JNICALL Java_com_microsoft_applicationinsights_internal_perfcounter_JniPCConnector_getInstanceName( - JNIEnv * env, - jclass clz, - jint processId) -{ - try - { - String^ result = getInstanceName(processId); - if (result == nullptr) - { - return nullptr; - } - std::string a; - MarshalString(result, a); - jstring r = env->NewStringUTF(a.c_str()); - return r; - } - catch (...) - { - return false; - } -} - -JNIEXPORT jstring JNICALL Java_com_microsoft_applicationinsights_internal_perfcounter_JniPCConnector_addCounter( - JNIEnv *env, - jclass clz, - jstring rawPerformanceCounterCategoryName, - jstring rawPerformanceCounterCounterName, - jstring rawPerformanceCounterInstance) -{ - try - { - jboolean copy; - const char *performanceCounterCategoryName = env->GetStringUTFChars(rawPerformanceCounterCategoryName, ©); - jboolean copy1; - const char *performanceCounterCounterName = env->GetStringUTFChars(rawPerformanceCounterCounterName, ©1); - jboolean copy2; - const char *performanceCounterInstance = env->GetStringUTFChars(rawPerformanceCounterInstance, ©2); - String^ value = addProcessCounter(performanceCounterCategoryName, performanceCounterCounterName, performanceCounterInstance); - - env->ReleaseStringUTFChars(rawPerformanceCounterCategoryName, performanceCounterCategoryName); - env->ReleaseStringUTFChars(rawPerformanceCounterCounterName, performanceCounterCounterName); - env->ReleaseStringUTFChars(rawPerformanceCounterInstance, performanceCounterInstance); - - if (value == nullptr) { - return nullptr; - } else { - std::string a; - MarshalString(value, a); - jstring r = env->NewStringUTF(a.c_str()); - return r; - } - } - catch (...) - { - return nullptr; - } -} - -JNIEXPORT jdouble JNICALL Java_com_microsoft_applicationinsights_internal_perfcounter_JniPCConnector_getPerformanceCounterValue( - JNIEnv *env, - jclass clz, - jstring name) -{ - try - { - jboolean copy; - const char *performanceCounterName = env->GetStringUTFChars(name, ©); - double value = getPerfCounterValue(performanceCounterName); - env->ReleaseStringUTFChars(name, performanceCounterName); - - return value; - } - catch (...) - { - return EXCEPTION_IN_GET_PERF_COUNTER_WRAPPER_FUNCTION_EXCEPTION; - } -} diff --git a/core/src/windows/cpp/CppPerfCounters.h b/core/src/windows/cpp/CppPerfCounters.h deleted file mode 100644 index 736181ad064..00000000000 --- a/core/src/windows/cpp/CppPerfCounters.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include - -#ifndef _CPPPERFCOUNTERS_H_ -#define _CPPPERFCOUNTERS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - /** - * Get the Windows instnace name of the current JVM process - */ - JNIEXPORT jstring JNICALL Java_com_microsoft_applicationinsights_internal_perfcounter_JniPCConnector_getInstanceName - (JNIEnv *, jclass, jint); - - /** - * Add Performance Counter by suppling its category name, counter name and instance name, the function returns a key - */ - JNIEXPORT jstring JNICALL Java_com_microsoft_applicationinsights_internal_perfcounter_JniPCConnector_addCounter - (JNIEnv *, jclass, jstring, jstring, jstring); - - /** - * Get the value of a Perfomance Counter by supplying its key as we got it from the '...._addCounter' function. - */ - JNIEXPORT jdouble JNICALL Java_com_microsoft_applicationinsights_internal_perfcounter_JniPCConnector_getPerformanceCounterValue - (JNIEnv *, jclass, jstring); -#ifdef __cplusplus -} -#endif -#endif // _CPPPERFCOUNTERS_H_ - diff --git a/core/src/windows/cpp/CppPerfCounters.vcxproj b/core/src/windows/cpp/CppPerfCounters.vcxproj deleted file mode 100644 index 7ef14acc7bd..00000000000 --- a/core/src/windows/cpp/CppPerfCounters.vcxproj +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {718BA051-0638-44AB-A58E-2DB851E94BD7} - v4.5 - ManagedCProj - CppPerfCounters - - - - DynamicLibrary - true - v120 - true - Unicode - - - DynamicLibrary - true - v120 - true - Unicode - - - DynamicLibrary - false - v120 - true - Unicode - - - DynamicLibrary - false - v120 - true - Unicode - - - - - - - - - - - - - - - - - - - true - $(IncludePath) - true - - - true - $(VC_IncludePath);$(WindowsSDK_IncludePath);$(IncludePath) - AIWinNativePC64 - - - false - - - false - - - - Level3 - Disabled - _DEBUG;%(PreprocessorDefinitions) - NotUsing - $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32 - true - - - true - - - - - - - Level3 - Disabled - WIN32;_DEBUG;%(PreprocessorDefinitions) - Use - - - true - - - - - - - Level3 - WIN32;NDEBUG;%(PreprocessorDefinitions) - NotUsing - $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32 - - - true - - - - - - Level3 - WIN32;NDEBUG;%(PreprocessorDefinitions) - Use - $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32 - - - true - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/src/windows/cpp/CppPerfCounters.vcxproj.filters b/core/src/windows/cpp/CppPerfCounters.vcxproj.filters deleted file mode 100644 index ec3e37adbd9..00000000000 --- a/core/src/windows/cpp/CppPerfCounters.vcxproj.filters +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - - - Source Files - - - \ No newline at end of file diff --git a/etw/java/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/diagnostics/etw/DllFileUtils.java b/etw/java/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/diagnostics/etw/DllFileUtils.java index 3b57bd20cf4..d8a4c2773c3 100644 --- a/etw/java/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/diagnostics/etw/DllFileUtils.java +++ b/etw/java/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/diagnostics/etw/DllFileUtils.java @@ -37,11 +37,9 @@ class DllFileUtils { private DllFileUtils() {} - // From JniPCConnector in applicationinsights-core public static final String AI_BASE_FOLDER = "AISDK"; public static final String AI_NATIVE_FOLDER = "native"; - // from :core:JniPCConnector.java public static File buildDllLocalPath(String versionDirectory) { File dllPath = getTempDir(); From acb284e1898fdb07a4f31796e1607f8abcd4f7c8 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 20 Mar 2021 10:56:14 -0700 Subject: [PATCH 12/16] Replace unix perf counters also --- .../perfcounter/ProcessBuiltInPerformanceCountersFactory.java | 2 +- .../internal/perfcounter/UnixProcessIOPerformanceCounter.java | 4 ++-- .../internal/perfcounter/UnixTotalCpuPerformanceCounter.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java index f5d7d8bf669..eee0cdeadc1 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java @@ -92,7 +92,7 @@ private Collection getUnixPerformanceCounters() { ArrayList performanceCounters = getMutualPerformanceCounters(); performanceCounters.add(new UnixProcessIOPerformanceCounter()); performanceCounters.add(new UnixTotalCpuPerformanceCounter()); - + performanceCounters.add(new OshiPerformanceCounter()); return performanceCounters; } diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java index 533a8694a9e..37392b33c25 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java @@ -76,8 +76,8 @@ public void report(TelemetryClient telemetryClient) { double value = (processIO - prevProcessIO) / timeElapsedInSeconds; prevProcessIO = processIO; - logger.trace("Sending Performance Counter: {} {}: {}", getProcessCategoryName(), PROCESS_IO_PC_METRIC_NAME, value); - MetricTelemetry telemetry = new MetricTelemetry(PROCESS_IO_PC_METRIC_NAME, value); + logger.trace("Sending Performance Counter: {} {}: {}", getProcessCategoryName(), PROCESS_IO_PC_METRIC_NAME + " FROM JNI", value); + MetricTelemetry telemetry = new MetricTelemetry(PROCESS_IO_PC_METRIC_NAME + " FROM JNI", value); telemetryClient.track(telemetry); } diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java index 8967aa2006a..885902cedce 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java @@ -84,8 +84,8 @@ public void report(TelemetryClient telemetryClient) { double totalCpuUsage = calculateTotalCpuUsage(array); - logger.trace("Sending Performance Counter: {}: {}", TOTAL_CPU_PC_METRIC_NAME, totalCpuUsage); - MetricTelemetry telemetry = new MetricTelemetry(TOTAL_CPU_PC_METRIC_NAME, totalCpuUsage); + logger.trace("Sending Performance Counter: {}: {}", TOTAL_CPU_PC_METRIC_NAME + " FROM JNI", totalCpuUsage); + MetricTelemetry telemetry = new MetricTelemetry(TOTAL_CPU_PC_METRIC_NAME + " FROM JNI", totalCpuUsage); telemetryClient.track(telemetry); } } From 7140a6e27df9480ea060eb950a769251bbba6845 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 20 Mar 2021 11:38:58 -0700 Subject: [PATCH 13/16] Remove old unix counters --- core/spotbugs.exclude.xml | 18 --- .../AbstractUnixPerformanceCounter.java | 64 -------- ...cessBuiltInPerformanceCountersFactory.java | 18 +-- .../perfcounter/UnixParsingState.java | 51 ------ .../UnixProcessIOPerformanceCounter.java | 120 -------------- .../perfcounter/UnixProcessIOtParser.java | 75 --------- .../UnixTotalCpuPerformanceCounter.java | 149 ------------------ .../perfcounter/UnixProcessIOtParserTest.java | 60 ------- 8 files changed, 1 insertion(+), 554 deletions(-) delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractUnixPerformanceCounter.java delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixParsingState.java delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParser.java delete mode 100644 core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java delete mode 100644 core/src/test/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParserTest.java diff --git a/core/spotbugs.exclude.xml b/core/spotbugs.exclude.xml index 3c96c2f2f58..d1983799de8 100644 --- a/core/spotbugs.exclude.xml +++ b/core/spotbugs.exclude.xml @@ -48,19 +48,6 @@ - - - - - - - - - - - - - @@ -127,11 +114,6 @@ - - - - - diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractUnixPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractUnixPerformanceCounter.java deleted file mode 100644 index f009828e7b3..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/AbstractUnixPerformanceCounter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import java.io.File; - -import com.microsoft.applicationinsights.internal.system.SystemInformation; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A base class for Unix performance counters who uses the '/proc/' filesystem for their work. - * - * Created by gupele on 3/8/2015. - */ -abstract class AbstractUnixPerformanceCounter extends AbstractPerformanceCounter { - - private static final Logger logger = LoggerFactory.getLogger(AbstractUnixPerformanceCounter.class); - - private final File processFile; - private final String path; - - protected AbstractUnixPerformanceCounter(String path) { - Preconditions.checkArgument(SystemInformation.INSTANCE.isUnix(), "This performance counter must be activated in Unix environment."); - Preconditions.checkArgument(!Strings.isNullOrEmpty(path), "path should be non null, non empty value."); - - this.path = path; - processFile = new File(path); - if (!processFile.canRead()) { - logPerfCounterErrorError("Can not read"); - } - } - - protected void logPerfCounterErrorError(String format, Object... args) { - format = "Performance Counter " + getId() + ": Error in file '" + path + "': " + format; - logger.error(format, args); - } - - protected File getProcessFile() { - return processFile; - } -} diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java index eee0cdeadc1..a4ab90015f2 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java @@ -90,8 +90,6 @@ private ArrayList getMutualPerformanceCounters() { */ private Collection getUnixPerformanceCounters() { ArrayList performanceCounters = getMutualPerformanceCounters(); - performanceCounters.add(new UnixProcessIOPerformanceCounter()); - performanceCounters.add(new UnixTotalCpuPerformanceCounter()); performanceCounters.add(new OshiPerformanceCounter()); return performanceCounters; } @@ -102,21 +100,7 @@ private Collection getUnixPerformanceCounters() { */ private Collection getWindowsPerformanceCounters() { ArrayList performanceCounters = getMutualPerformanceCounters(); - - try { - performanceCounters.add(new OshiPerformanceCounter()); - } catch (ThreadDeath td) { - throw td; - } catch (Throwable e) { - try { - logger.error("Failed to create OshiPerformanceCounter: '{}'", e.toString()); - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t2) { - // chomp - } - } - + performanceCounters.add(new OshiPerformanceCounter()); return performanceCounters; } } diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixParsingState.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixParsingState.java deleted file mode 100644 index 427ebbf113c..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixParsingState.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -/** - * Created by gupele on 3/16/2015. - */ -public class UnixParsingState { - private int doneCounter; - - private double returnValue; - - public UnixParsingState(int doneCounter) { - this.doneCounter = doneCounter; - } - - public int getDoneCounter() { - return doneCounter; - } - - public void decrementDoneCounter() { - this.doneCounter--; - } - - public double getReturnValue() { - return returnValue; - } - - public void addToReturnValue(double addend) { - this.returnValue += addend; - } -} diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java deleted file mode 100644 index 37392b33c25..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOPerformanceCounter.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import java.io.BufferedReader; -import java.io.FileReader; - -import com.microsoft.applicationinsights.TelemetryClient; -import com.microsoft.applicationinsights.internal.system.SystemInformation; -import com.microsoft.applicationinsights.telemetry.MetricTelemetry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static com.microsoft.applicationinsights.internal.perfcounter.Constants.PROCESS_IO_PC_METRIC_NAME; - -/** - * The class knows how to supply the io usage of the current process under the Unix OS. - * - * When activated the class will calculate the io usage based on the data under /proc/[pid]/io - * file and will create a {@link com.microsoft.applicationinsights.telemetry.MetricTelemetry} - * that will contain that data per the amount of time elapsed from the last check in seconds. - * - * Created by gupele on 3/8/2015. - */ -final class UnixProcessIOPerformanceCounter extends AbstractUnixPerformanceCounter { - - private static final Logger logger = LoggerFactory.getLogger(UnixProcessIOPerformanceCounter.class); - - private final static double NANOS_IN_SECOND = 1000000000.0; - - private double prevProcessIO; - - private long lastCollectionInNanos = -1; - - public UnixProcessIOPerformanceCounter() { - super("/proc/" + SystemInformation.INSTANCE.getProcessId() + "/io"); - } - - @Override - public String getId() { - return Constants.PROCESS_IO_PC_ID; - } - - @Override - public void report(TelemetryClient telemetryClient) { - long currentCollectionInNanos = System.nanoTime(); - - Double processIO = getCurrentIOForCurrentProcess(); - if (processIO == null) { - return; - } - if (lastCollectionInNanos != -1) { - // Not the first time - - double timeElapsedInSeconds = ((double)(currentCollectionInNanos - lastCollectionInNanos)) / NANOS_IN_SECOND; - - double value = (processIO - prevProcessIO) / timeElapsedInSeconds; - prevProcessIO = processIO; - - logger.trace("Sending Performance Counter: {} {}: {}", getProcessCategoryName(), PROCESS_IO_PC_METRIC_NAME + " FROM JNI", value); - MetricTelemetry telemetry = new MetricTelemetry(PROCESS_IO_PC_METRIC_NAME + " FROM JNI", value); - telemetryClient.track(telemetry); - } - - prevProcessIO = processIO; - lastCollectionInNanos = currentCollectionInNanos; - } - - /** - * - * @return the current IO for current process, or null if the datum could not be measured. - */ - public Double getCurrentIOForCurrentProcess() { - BufferedReader bufferedReader = null; - - Double result; - UnixProcessIOtParser parser = new UnixProcessIOtParser(); - try { - bufferedReader = new BufferedReader(new FileReader(getProcessFile())); - String line; - while (!parser.done() && (line = bufferedReader.readLine()) != null) { - parser.process(line); - } - - result = parser.getValue(); - } catch (Exception e) { - result = null; - logPerfCounterErrorError("Error while parsing file: '{}'", PROCESS_IO_PC_METRIC_NAME, e); - } finally { - if (bufferedReader != null ) { - try { - bufferedReader.close(); - } catch (Exception e) { - logPerfCounterErrorError("Error while closing file : '{}'", e); - } - } - } - - return result; - } -} diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParser.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParser.java deleted file mode 100644 index 6205eebee6c..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParser.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by gupele on 3/16/2015. - */ -final class UnixProcessIOtParser { - - private static final Logger logger = LoggerFactory.getLogger(UnixProcessIOtParser.class); - - private static final String READ_BYTES_PART = "read_bytes:"; - private static final String WRITE_BYTES_PART = "write_bytes:"; - - private final UnixParsingState state = new UnixParsingState(2); - private boolean readBytesDone = false; - private boolean writeBytesDone = false; - - boolean done() { - return state.getDoneCounter() == 0; - } - - double getValue() { - return state.getReturnValue(); - } - - void process(String line) { - if (!readBytesDone && parseValue(line, READ_BYTES_PART)) { - readBytesDone = true; - return; - } - if (!writeBytesDone && parseValue(line, WRITE_BYTES_PART)) { - writeBytesDone = true; - } - } - - private boolean parseValue(String line, String part) { - int index = line.indexOf(part); - if (index != -1) { - String doubleValueAsString = line.substring(index + part.length()); - try { - state.addToReturnValue(Double.parseDouble(doubleValueAsString.trim())); - state.decrementDoneCounter(); - return true; - } catch (Exception e) { - logger.error("Error in parsing value of UnixProcess counter"); - logger.trace("Error in parsing value of UnixProcess counter", e); - } - } - - return false; - } -} diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java deleted file mode 100644 index 885902cedce..00000000000 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/UnixTotalCpuPerformanceCounter.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.util.ArrayList; - -import com.microsoft.applicationinsights.TelemetryClient; -import com.microsoft.applicationinsights.telemetry.MetricTelemetry; - -import com.google.common.base.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static com.microsoft.applicationinsights.internal.perfcounter.Constants.TOTAL_CPU_PC_METRIC_NAME; - -/** - * The class supplies the overall cpu usage of the machine. - * - * Created by gupele on 3/8/2015. - */ -final class UnixTotalCpuPerformanceCounter extends AbstractUnixPerformanceCounter { - - private static final Logger logger = LoggerFactory.getLogger(UnixTotalCpuPerformanceCounter.class); - - private final static String STAT_FILE = "/proc/stat"; - - private long[] prevCpuCounters; - private long prevTotalCpuValue; - - public UnixTotalCpuPerformanceCounter() { - super(STAT_FILE); - prevCpuCounters = null; - } - - @Override - public String getId() { - return Constants.TOTAL_CPU_PC_ID; - } - - @Override - public void report(TelemetryClient telemetryClient) { - String line = getLineOfData(); - - if (!Strings.isNullOrEmpty(line)) { - String[] rawStringValues = line.split(" "); - - ArrayList stringValues = new ArrayList<>(rawStringValues.length - 1); - for (int i = 1; i < rawStringValues.length; ++i) { - String stringValue = rawStringValues[i]; - if (Strings.isNullOrEmpty(stringValue)) { - continue; - } - - stringValues.add(stringValue); - } - - String[] array = stringValues.toArray(new String[stringValues.size()]); - - if (prevCpuCounters == null) { - getCountersForTheFirstTime(array); - return; - } - - double totalCpuUsage = calculateTotalCpuUsage(array); - - logger.trace("Sending Performance Counter: {}: {}", TOTAL_CPU_PC_METRIC_NAME + " FROM JNI", totalCpuUsage); - MetricTelemetry telemetry = new MetricTelemetry(TOTAL_CPU_PC_METRIC_NAME + " FROM JNI", totalCpuUsage); - telemetryClient.track(telemetry); - } - } - - private String getLineOfData() { - BufferedReader bufferedReader = null; - - String line = null; - try { - bufferedReader = new BufferedReader(new FileReader(getProcessFile())); - line = bufferedReader.readLine(); - } catch (Exception e) { - logPerfCounterErrorError("Error while parsing file: ", e); - } finally { - if (bufferedReader != null ) { - try { - bufferedReader.close(); - } catch (Exception e) { - logPerfCounterErrorError("Error while closing file: ", e); - } - } - } - - return line; - } - - private void getCountersForTheFirstTime(String[] stringValues) { - prevCpuCounters = new long[stringValues.length]; - prevTotalCpuValue = 0; - for (int i = 0; i < stringValues.length; ++i) { - String stringValue = stringValues[i]; - long value = Long.parseLong(stringValue); - prevCpuCounters[i] = value; - prevTotalCpuValue += value; - } - } - - private double calculateTotalCpuUsage(String[] stringValues) { - long[] cpuCounters = new long[stringValues.length]; - long totalCpuValue = 0; - double diffIdle = 0.0; - for (int i = 0; i < stringValues.length; ++i) { - String stringValue = stringValues[i]; - long value = Long.parseLong(stringValue); - cpuCounters[i] = value - prevCpuCounters[i]; - prevCpuCounters[i] = value; - - totalCpuValue += value; - if (i == 3) { - diffIdle = cpuCounters[i]; - } - } - - double totalDiff = totalCpuValue - prevTotalCpuValue; - double result = 100 * ((totalDiff - diffIdle) / (totalDiff)); - - prevTotalCpuValue = totalCpuValue; - - return result; - } -} diff --git a/core/src/test/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParserTest.java b/core/src/test/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParserTest.java deleted file mode 100644 index 972f843e6e6..00000000000 --- a/core/src/test/java/com/microsoft/applicationinsights/internal/perfcounter/UnixProcessIOtParserTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ApplicationInsights-Java - * Copyright (c) Microsoft Corporation - * All rights reserved. - * - * MIT License - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the ""Software""), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, and to permit - * persons to whom the Software is furnished to do so, subject to the following conditions: - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -package com.microsoft.applicationinsights.internal.perfcounter; - -import org.junit.Test; - -import static org.junit.Assert.*; - -public final class UnixProcessIOtParserTest { - @Test - public void testProcess() { - UnixProcessIOtParser parser = new UnixProcessIOtParser(); - - parser.process("rchar: 1661777"); - assertFalse(parser.done()); - - parser.process("wchar: 7431"); - assertFalse(parser.done()); - - parser.process("syscr: 1240"); - assertFalse(parser.done()); - - parser.process("syscw: 123"); - assertFalse(parser.done()); - - parser.process("read_bytes: 7335936"); - assertFalse(parser.done()); - - parser.process("write_bytes: 12288"); - assertTrue(parser.done()); - assertEquals(7335936 + 12288, parser.getValue(), 0.0); - - parser.process("cancelled_write_bytes: 0"); - assertTrue(parser.done()); - assertEquals(7335936 + 12288, parser.getValue(), 0.0); - - parser.process("write_bytes: 12288"); - assertTrue(parser.done()); - assertEquals(7335936 + 12288, parser.getValue(), 0.0); - } -} From 235b9db7095e9352e2bf639a8f34976625b6b5a0 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 20 Mar 2021 11:40:09 -0700 Subject: [PATCH 14/16] Remove unused constants --- .../internal/perfcounter/Constants.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/Constants.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/Constants.java index 6701dbbf2fa..35059466cf4 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/Constants.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/Constants.java @@ -27,32 +27,22 @@ public final class Constants { public final static String PERFORMANCE_COUNTER_PREFIX = "JSDK_"; - public final static String TOTAL_CPU_PC_ID = PERFORMANCE_COUNTER_PREFIX + "TotalCpuPerformanceCounter"; - public final static String PROCESS_CPU_PC_ID = PERFORMANCE_COUNTER_PREFIX + "ProcessCpuPerformanceCounter"; - public final static String TOTAL_CPU_PC_CATEGORY_NAME = "Processor"; public final static String TOTAL_CPU_PC_METRIC_NAME = "\\Processor(_Total)\\% Processor Time"; public final static String PROCESS_CPU_PC_METRIC_NAME = "\\Process(??APP_WIN32_PROC??)\\% Processor Time"; - public final static String CPU_PC_COUNTER_NAME = "% Processor Time"; public final static String TOTAL_MEMORY_PC_ID = PERFORMANCE_COUNTER_PREFIX + "TotalMemoryPerformanceCounter"; public final static String PROCESS_MEM_PC_ID = PERFORMANCE_COUNTER_PREFIX + "ProcessMemoryPerformanceCounter"; public final static String PROCESS_MEM_PC_METRICS_NAME = "\\Process(??APP_WIN32_PROC??)\\Private Bytes"; - public final static String PROCESS_MEM_PC_COUNTER_NAME = "Private Bytes"; public final static String TOTAL_MEMORY_PC_METRIC_NAME = "\\Memory\\Available Bytes"; - public final static String PROCESS_IO_PC_ID = PERFORMANCE_COUNTER_PREFIX + "ProcessIOPerformanceCounter"; public final static String PROCESS_IO_PC_METRIC_NAME = "\\Process(??APP_WIN32_PROC??)\\IO Data Bytes/sec"; - public final static String PROCESS_IO_PC_COUNTER_NAME = "IO Data Bytes/sec"; - - public final static String INSTANCE_NAME_TOTAL = "_Total"; public final static String PROCESS_CATEGORY = "Process"; - private Constants() { } } From 45c2c64bbbdc579e0994a576f85836dd5795aa81 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 20 Mar 2021 11:42:49 -0700 Subject: [PATCH 15/16] Unify windows and unix code --- ...cessBuiltInPerformanceCountersFactory.java | 55 +------------------ 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java index a4ab90015f2..138a9769e48 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java +++ b/core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/ProcessBuiltInPerformanceCountersFactory.java @@ -23,9 +23,7 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import com.microsoft.applicationinsights.internal.system.SystemInformation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,8 +34,6 @@ */ final class ProcessBuiltInPerformanceCountersFactory implements PerformanceCountersFactory { - private static final Logger logger = LoggerFactory.getLogger(ProcessBuiltInPerformanceCountersFactory.class); - /** * Creates the {@link com.microsoft.applicationinsights.internal.perfcounter.PerformanceCounter} that are * the 'built-in' performance counters of the process. @@ -47,60 +43,11 @@ final class ProcessBuiltInPerformanceCountersFactory implements PerformanceCount * @return A collection of {@link com.microsoft.applicationinsights.internal.perfcounter.PerformanceCounter} */ public Collection getPerformanceCounters() { - try { - if (SystemInformation.INSTANCE.isWindows()) { - return getWindowsPerformanceCounters(); - } else if (SystemInformation.INSTANCE.isUnix()) { - return getUnixPerformanceCounters(); - } else { - logger.error("Unknown OS, performance counters are not created."); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t) { - try { - logger.error("Error while creating performance counters: '{}'", t.toString()); - } catch (ThreadDeath td) { - throw td; - } catch (Throwable t2) { - // chomp - } - } - - return Collections.emptyList(); - } - - /** - * Creates the performance counters that are suitable for all supported OSs. - * @return An array of generic performance counters. - */ - private ArrayList getMutualPerformanceCounters() { ArrayList performanceCounters = new ArrayList<>(); - performanceCounters.add(new ProcessCpuPerformanceCounter()); performanceCounters.add(new ProcessMemoryPerformanceCounter()); performanceCounters.add(new FreeMemoryPerformanceCounter()); - - return performanceCounters; - } - - /** - * Returns the performance counters that are useful for Unix OS. - * @return Collection of Windows performance counters. - */ - private Collection getUnixPerformanceCounters() { - ArrayList performanceCounters = getMutualPerformanceCounters(); - performanceCounters.add(new OshiPerformanceCounter()); - return performanceCounters; - } - - /** - * Returns the performance counters that are useful for Windows OSs. - * @return Collection of Unix performance counters. - */ - private Collection getWindowsPerformanceCounters() { - ArrayList performanceCounters = getMutualPerformanceCounters(); - performanceCounters.add(new OshiPerformanceCounter()); + performanceCounters.add(new OshiPerformanceCounter()); // system cpu and process disk i/o return performanceCounters; } } From 69803bc403e2476d35aad6bcf285c3a02776f0be Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 21 Mar 2021 21:37:51 -0700 Subject: [PATCH 16/16] Merge conflicts --- .pipelines/pipeline.user.windows.buddy.yml | 20 +------------- .pipelines/pipeline.user.windows.official.yml | 20 +------------- .pipelines/pipeline.user.windows.yml | 8 ------ .scripts/installWindows81Sdk.cmd | 26 ------------------- .../compileClasspath.lockfile | 3 +++ .../runtimeClasspath.lockfile | 3 +++ .../compileClasspath.lockfile | 5 +++- .../runtimeClasspath.lockfile | 5 +++- .../compileClasspath.lockfile | 3 +++ .../runtimeClasspath.lockfile | 3 +++ .../compileClasspath.lockfile | 5 +++- .../runtimeClasspath.lockfile | 5 +++- 12 files changed, 30 insertions(+), 76 deletions(-) delete mode 100644 .scripts/installWindows81Sdk.cmd diff --git a/.pipelines/pipeline.user.windows.buddy.yml b/.pipelines/pipeline.user.windows.buddy.yml index b6a43f83fe2..c25f3faafa4 100644 --- a/.pipelines/pipeline.user.windows.buddy.yml +++ b/.pipelines/pipeline.user.windows.buddy.yml @@ -6,28 +6,10 @@ version: system: 'custom' build: commands: - - !!buildcommand - name: 'Assemble Perf Counters DLL' - command: '.scripts/gradle.cmd' - arguments: ':core:windowsSharedLibrary' - artifacts: - - from: 'core/build/libs/windows/shared' - include: - - '**/*' - exclude: - - '**/*.pdb' - signing_options: - profile: external_distribution - sign_inline: true - logs: - - to: 'PerfCounters DLL Build Logs' - from: 'core/build/tmp' - include: - - '*WindowsCpp/*' - !!buildcommand name: 'Assemble ApplicationInsights-Java JARs' command: '.scripts/gradle.cmd' - arguments: 'assemble -Pcore.native.artifacts.prebuilt=true' + arguments: 'assemble' artifacts: - to: 'Artifacts' include: diff --git a/.pipelines/pipeline.user.windows.official.yml b/.pipelines/pipeline.user.windows.official.yml index a33a430731f..8b3fb9a3088 100644 --- a/.pipelines/pipeline.user.windows.official.yml +++ b/.pipelines/pipeline.user.windows.official.yml @@ -5,28 +5,10 @@ version: system: 'custom' build: commands: - - !!buildcommand - name: 'Assemble Perf Counters DLL' - command: '.scripts/gradle.cmd' - arguments: ':core:windowsSharedLibrary' - artifacts: - - from: 'core/build/libs/windows/shared' - include: - - '**/*' - exclude: - - '**/*.pdb' - signing_options: - profile: external_distribution - sign_inline: true - logs: - - to: 'PerfCounters DLL Build Logs' - from: 'core/build/tmp' - include: - - '*WindowsCpp/*' - !!buildcommand name: 'Assemble ApplicationInsights-Java JARs' command: '.scripts/gradle.cmd' - arguments: 'assemble -Pcore.native.artifacts.prebuilt=true -DisRelease=true -Pai.etw.native.build=release' + arguments: 'assemble -DisRelease=true -Pai.etw.native.build=release' artifacts: - to: 'Artifacts' include: diff --git a/.pipelines/pipeline.user.windows.yml b/.pipelines/pipeline.user.windows.yml index f53a102f340..8557c143d86 100644 --- a/.pipelines/pipeline.user.windows.yml +++ b/.pipelines/pipeline.user.windows.yml @@ -20,14 +20,6 @@ static_analysis_options: fail_on_error: true restore: commands: - - !!defaultcommand - name: 'Install Windows 8.1 SDK' - command: '.scripts/installWindows81Sdk.cmd' - logs: - - from: 'WinSdkInstall' - to: 'WinSdkInstall' - include: - - '**/*.log' - !!defaultcommand name: 'Install Windows 10 SDK' command: '.scripts/installWindows10Sdk.cmd' diff --git a/.scripts/installWindows81Sdk.cmd b/.scripts/installWindows81Sdk.cmd deleted file mode 100644 index 331dabb395c..00000000000 --- a/.scripts/installWindows81Sdk.cmd +++ /dev/null @@ -1,26 +0,0 @@ -@echo off - -echo "Installing Windows 8.1 SDK..." - -:: --------------------------- -:: Windows Software Development Kit for Windows 8.1 -:: --------------------------- -:: Available features: (Features marked with * can be downloaded but cannot be installed on this computer) -:: OptionId.WindowsDesktopSoftwareDevelopmentKit -:: OptionId.WindowsPerformanceToolkit -:: OptionId.WindowsDesktopDebuggers -:: OptionId.AvrfExternal -:: OptionId.NetFxSoftwareDevelopmentKit -:: OptionId.WindowsSoftwareLogoToolkit -:: OptionId.MSIInstallTools -:: * OptionId.Netfx - -powershell -NoProfile -ExecutionPolicy Unrestricted -File "%~dp0install-something.ps1" -Install -Url "http://download.microsoft.com/download/B/0/C/B0C80BA3-8AD6-4958-810B-6882485230B5/standalonesdk/sdksetup.exe" -InstallerArgs "/features OptionId.WindowsDesktopSoftwareDevelopmentKit OptionId.WindowsPerformanceToolkit OptionId.NetFxSoftwareDevelopmentKit /log %CDP_USER_SOURCE_FOLDER_CONTAINER_PATH%\WinSdkInstall\winsdkinstall.log /norestart /q" -InstallationDirectory "C:\Program Files (x86)\Windows Kits\8.1" -HomeVar "APPINSIGHTS_WIN81_SDK_PATH" -CleanOnFinish || exit /B 1 - -echo "C:\Program Files (x86)\Windows Kits\8.1" -dir "C:\Program Files (x86)\Windows Kits\8.1" - -echo "%CDP_USER_SOURCE_FOLDER_CONTAINER_PATH%\WinSdkInstall" -dir "%CDP_USER_SOURCE_FOLDER_CONTAINER_PATH%\WinSdkInstall" - -echo "Windows 8.1 SDK Installed Successfully" \ No newline at end of file diff --git a/agent/agent-tooling/gradle/dependency-locks/compileClasspath.lockfile b/agent/agent-tooling/gradle/dependency-locks/compileClasspath.lockfile index d74dcc59a72..abcc1c4346f 100644 --- a/agent/agent-tooling/gradle/dependency-locks/compileClasspath.lockfile +++ b/agent/agent-tooling/gradle/dependency-locks/compileClasspath.lockfile @@ -5,6 +5,7 @@ ch.qos.logback.contrib:logback-json-classic:0.1.5 ch.qos.logback.contrib:logback-json-core:0.1.5 ch.qos.logback:logback-classic:1.2.3 ch.qos.logback:logback-core:1.2.3 +com.github.oshi:oshi-core:5.6.0 com.google.code.findbugs:jsr305:3.0.2 com.google.code.gson:gson:2.8.2 com.google.errorprone:error_prone_annotations:2.2.0 @@ -35,6 +36,8 @@ io.opentelemetry:opentelemetry-sdk-trace:1.0.0 io.opentelemetry:opentelemetry-sdk:1.0.0 io.opentelemetry:opentelemetry-semconv:1.0.1-alpha net.bytebuddy:byte-buddy:1.10.10 +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 diff --git a/agent/agent-tooling/gradle/dependency-locks/runtimeClasspath.lockfile b/agent/agent-tooling/gradle/dependency-locks/runtimeClasspath.lockfile index 3ea4659cdcd..11b417183cd 100644 --- a/agent/agent-tooling/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/agent/agent-tooling/gradle/dependency-locks/runtimeClasspath.lockfile @@ -2,6 +2,7 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. com.blogspot.mydailyjava:weak-lock-free:0.15 +com.github.oshi:oshi-core:5.6.0 com.google.auto.service:auto-service-annotations:1.0-rc7 com.google.auto.service:auto-service:1.0-rc7 com.google.auto:auto-common:0.10 @@ -43,6 +44,8 @@ io.prometheus:simpleclient_common:0.9.0 io.prometheus:simpleclient_httpserver:0.9.0 net.bytebuddy:byte-buddy-agent:1.10.18 net.bytebuddy:byte-buddy:1.10.18 +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 diff --git a/agent/exporter/gradle/dependency-locks/compileClasspath.lockfile b/agent/exporter/gradle/dependency-locks/compileClasspath.lockfile index 61db88aede5..4f2cb32488b 100644 --- a/agent/exporter/gradle/dependency-locks/compileClasspath.lockfile +++ b/agent/exporter/gradle/dependency-locks/compileClasspath.lockfile @@ -1,6 +1,7 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.github.oshi:oshi-core:5.6.0 com.google.code.findbugs:jsr305:3.0.2 com.google.code.gson:gson:2.8.2 com.google.errorprone:error_prone_annotations:2.2.0 @@ -22,10 +23,12 @@ io.opentelemetry:opentelemetry-sdk-common:1.0.0 io.opentelemetry:opentelemetry-sdk-trace:1.0.0 io.opentelemetry:opentelemetry-sdk:1.0.0 io.opentelemetry:opentelemetry-semconv:1.0.1-alpha +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 org.apache.httpcomponents:httpcore:4.4.13 org.checkerframework:checker-compat-qual:2.5.2 org.codehaus.mojo:animal-sniffer-annotations:1.17 -org.slf4j:slf4j-api:1.7.26 +org.slf4j:slf4j-api:1.7.30 diff --git a/agent/exporter/gradle/dependency-locks/runtimeClasspath.lockfile b/agent/exporter/gradle/dependency-locks/runtimeClasspath.lockfile index 1cfeafbfa52..bce3195045e 100644 --- a/agent/exporter/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/agent/exporter/gradle/dependency-locks/runtimeClasspath.lockfile @@ -1,6 +1,7 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.github.oshi:oshi-core:5.6.0 com.google.code.findbugs:jsr305:3.0.2 com.google.code.gson:gson:2.8.2 com.google.errorprone:error_prone_annotations:2.2.0 @@ -21,10 +22,12 @@ io.opentelemetry:opentelemetry-sdk-common:1.0.0 io.opentelemetry:opentelemetry-sdk-trace:1.0.0 io.opentelemetry:opentelemetry-sdk:1.0.0 io.opentelemetry:opentelemetry-semconv:1.0.0-alpha +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 org.apache.httpcomponents:httpcore:4.4.13 org.checkerframework:checker-compat-qual:2.5.2 org.codehaus.mojo:animal-sniffer-annotations:1.17 -org.slf4j:slf4j-api:1.7.26 +org.slf4j:slf4j-api:1.7.30 diff --git a/agent/instrumentation/gradle/dependency-locks/compileClasspath.lockfile b/agent/instrumentation/gradle/dependency-locks/compileClasspath.lockfile index fe944692fe2..7472f9ac32b 100644 --- a/agent/instrumentation/gradle/dependency-locks/compileClasspath.lockfile +++ b/agent/instrumentation/gradle/dependency-locks/compileClasspath.lockfile @@ -1,6 +1,7 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.github.oshi:oshi-core:5.6.0 com.google.code.findbugs:jsr305:3.0.2 com.google.code.gson:gson:2.8.2 com.google.errorprone:error_prone_annotations:2.2.0 @@ -85,6 +86,8 @@ io.opentelemetry:opentelemetry-sdk-trace:1.0.0 io.opentelemetry:opentelemetry-sdk:1.0.0 io.opentelemetry:opentelemetry-semconv:1.0.1-alpha net.bytebuddy:byte-buddy:1.10.10 +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 diff --git a/agent/instrumentation/gradle/dependency-locks/runtimeClasspath.lockfile b/agent/instrumentation/gradle/dependency-locks/runtimeClasspath.lockfile index 7a76a25d328..0afbd311093 100644 --- a/agent/instrumentation/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/agent/instrumentation/gradle/dependency-locks/runtimeClasspath.lockfile @@ -2,6 +2,7 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. com.blogspot.mydailyjava:weak-lock-free:0.15 +com.github.oshi:oshi-core:5.6.0 com.google.auto.service:auto-service-annotations:1.0-rc7 com.google.auto.service:auto-service:1.0-rc7 com.google.auto:auto-common:0.10 @@ -104,6 +105,8 @@ io.prometheus:simpleclient_common:0.9.0 io.prometheus:simpleclient_httpserver:0.9.0 net.bytebuddy:byte-buddy-agent:1.10.18 net.bytebuddy:byte-buddy:1.10.18 +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 diff --git a/core/gradle/dependency-locks/compileClasspath.lockfile b/core/gradle/dependency-locks/compileClasspath.lockfile index 5ad2cbdafa2..3fb34b84607 100644 --- a/core/gradle/dependency-locks/compileClasspath.lockfile +++ b/core/gradle/dependency-locks/compileClasspath.lockfile @@ -1,6 +1,7 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.github.oshi:oshi-core:5.6.0 com.google.code.findbugs:jsr305:3.0.2 com.google.code.gson:gson:2.8.2 com.google.errorprone:error_prone_annotations:2.2.0 @@ -14,10 +15,12 @@ commons-codec:commons-codec:1.11 commons-io:commons-io:2.6 commons-logging:commons-logging:1.2 eu.infomas:annotation-detector:3.0.5 +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 org.apache.httpcomponents:httpcore:4.4.13 org.checkerframework:checker-compat-qual:2.5.2 org.codehaus.mojo:animal-sniffer-annotations:1.17 -org.slf4j:slf4j-api:1.7.26 +org.slf4j:slf4j-api:1.7.30 diff --git a/core/gradle/dependency-locks/runtimeClasspath.lockfile b/core/gradle/dependency-locks/runtimeClasspath.lockfile index 5ad2cbdafa2..3fb34b84607 100644 --- a/core/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/core/gradle/dependency-locks/runtimeClasspath.lockfile @@ -1,6 +1,7 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. +com.github.oshi:oshi-core:5.6.0 com.google.code.findbugs:jsr305:3.0.2 com.google.code.gson:gson:2.8.2 com.google.errorprone:error_prone_annotations:2.2.0 @@ -14,10 +15,12 @@ commons-codec:commons-codec:1.11 commons-io:commons-io:2.6 commons-logging:commons-logging:1.2 eu.infomas:annotation-detector:3.0.5 +net.java.dev.jna:jna-platform:5.7.0 +net.java.dev.jna:jna:5.7.0 org.apache.commons:commons-lang3:3.11 org.apache.commons:commons-text:1.9 org.apache.httpcomponents:httpclient:4.5.13 org.apache.httpcomponents:httpcore:4.4.13 org.checkerframework:checker-compat-qual:2.5.2 org.codehaus.mojo:animal-sniffer-annotations:1.17 -org.slf4j:slf4j-api:1.7.26 +org.slf4j:slf4j-api:1.7.30