generated from newrelic-experimental/java-instrumentation-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
1,034 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
|
||
apply plugin: 'java' | ||
|
||
dependencies { | ||
// Declare a dependency on each JAR you want to instrument | ||
// Example: | ||
// implementation 'javax.servlet:servlet-api:2.5' | ||
|
||
// New Relic Java Agent dependencies | ||
implementation 'com.newrelic.agent.java:newrelic-agent:7.4.0' | ||
implementation 'com.newrelic.agent.java:newrelic-api:7.4.0' | ||
implementation fileTree(include: ['*.jar'], dir: 'lib') | ||
implementation fileTree(include: ['*.jar'], dir: '../libs') | ||
implementation fileTree(include: ['*.jar'], dir: '../test-lib') | ||
|
||
} | ||
|
||
|
||
|
||
jar { | ||
|
||
manifest { | ||
attributes 'Implementation-Title': 'com.newrelic.instrumentation.labs.sap-channel-monitoring' | ||
attributes 'Implementation-Vendor': 'New Relic Labs' | ||
attributes 'Implementation-Vendor-Id': 'com.newrelic.labs' | ||
attributes 'Implementation-Version': 1.0 | ||
attributes 'Agent-Class': 'com.newrelic.instrumentation.labs.sap.channel.monitoring.ChannelMonitoringPreMain' | ||
} | ||
} | ||
|
||
verifyInstrumentation { | ||
// Verifier plugin documentation: | ||
// https://github.com/newrelic/newrelic-gradle-verify-instrumentation | ||
// Example: | ||
// passes 'javax.servlet:servlet-api:[2.2,2.5]' | ||
// exclude 'javax.servlet:servlet-api:2.4.public_draft' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
com.sap.tc.cmi_api.jar | ||
com.sap.xi.mdt.itsam.lib.jar | ||
cpa_svc_api-1.0.0.jar | ||
sap.com~tc~lm~itsam~co~ui~xi~channel~wd.jar | ||
sap.com~tc~lm~itsam~ui~proxy.jar |
279 changes: 279 additions & 0 deletions
279
...rc/main/java/com/newrelic/instrumentation/labs/sap/channel/monitoring/ChannelMonitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
package com.newrelic.instrumentation.labs.sap.channel.monitoring; | ||
|
||
import java.util.Date; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
import java.util.concurrent.ScheduledFuture; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.logging.Level; | ||
|
||
import com.newrelic.api.agent.NewRelic; | ||
import com.sap.aii.af.service.administration.impl.AdminManagerImpl; | ||
import com.sap.aii.af.service.administration.monitoring.ActivationState; | ||
import com.sap.aii.af.service.administration.monitoring.ChannelActivationStatus; | ||
import com.sap.aii.af.service.administration.monitoring.ClusterChannelStatusOverview; | ||
import com.sap.aii.af.service.cpa.Channel; | ||
import com.sap.aii.mdt.itsam.mbeans.utils.XIAdapterChannelUtil; | ||
|
||
public class ChannelMonitor implements Runnable { | ||
|
||
public static boolean initialized = false; | ||
private static ChannelMonitoringConfig currentChannelConfig = null; | ||
protected static boolean enabled = true; | ||
private static ScheduledFuture<?> scheduledFuture = null; | ||
private static long collectionPeriod = 2L; | ||
private static ScheduledExecutorService executor; | ||
|
||
public static void init() { | ||
if(!initialized) { | ||
try { | ||
|
||
if(currentChannelConfig == null) { | ||
currentChannelConfig = ChannelMonitoringLogger.getConfig(); | ||
NewRelic.getAgent().getInsights().recordCustomEvent("ChannelMonitoringConfig", currentChannelConfig.getCurrentSettings()); | ||
} | ||
|
||
enabled = currentChannelConfig.isEnabled(); | ||
|
||
executor = Executors.newScheduledThreadPool(2); | ||
collectionPeriod = currentChannelConfig.getCollection_period(); | ||
NewRelic.getAgent().getLogger().log(Level.INFO, "Will collect channel status every {0} minutes", collectionPeriod); | ||
scheduledFuture = executor.scheduleAtFixedRate(new ChannelMonitor(), 1L, collectionPeriod, TimeUnit.MINUTES); | ||
initialized = true; | ||
NewRelic.getAgent().getLogger().log(java.util.logging.Level.FINE, ", log file is {0}",currentChannelConfig.getChannelLog()); | ||
|
||
} catch (Exception e) { | ||
NewRelic.getAgent().getLogger().log(java.util.logging.Level.FINE, e, "Failed to open channel monitoring log"); | ||
} | ||
|
||
|
||
} | ||
} | ||
|
||
protected static boolean reinitialScheduled(long n) { | ||
if(n == collectionPeriod) { | ||
// same period so noop | ||
return true; | ||
} | ||
// if monitor is currently running then cancel it | ||
if(scheduledFuture != null) { | ||
boolean b = scheduledFuture.cancel(true); | ||
// if false then unable to cancel so skip re-initialing | ||
if(!b) { | ||
NewRelic.getAgent().getLogger().log(Level.FINE, "Failed to stop Channel Montoring collector, skipping re-initialing with new collection period: {0}", n); | ||
return b; | ||
} | ||
} | ||
|
||
NewRelic.getAgent().getLogger().log(Level.INFO, "Will collect channel status every {0} minutes", collectionPeriod); | ||
scheduledFuture = executor.scheduleAtFixedRate(new ChannelMonitor(), n, n, TimeUnit.MINUTES); | ||
|
||
return true; | ||
|
||
} | ||
|
||
@Override | ||
public void run() { | ||
|
||
NewRelic.recordMetric("SAP/ChannelMonitoring/Collection",1); | ||
if(!enabled) { | ||
NewRelic.getAgent().getLogger().log(java.util.logging.Level.FINEST, "Channel Monitoring is disabled, skipping monitoring"); | ||
return; | ||
} | ||
|
||
if(!initialized) { | ||
init(); | ||
} | ||
|
||
try { | ||
Date collectionTime = new Date(); | ||
AdminManagerImpl adminManager = AdminManagerImpl.getInstance(); | ||
|
||
Channel[] allChannels = XIAdapterChannelUtil.getAllChannels(); | ||
|
||
HashSet<String> channelNames = new HashSet<>(); | ||
HashMap<String, String> idToChannel = new HashMap<>(); | ||
|
||
for(Channel channel : allChannels) { | ||
channelNames.add(channel.getChannelName()); | ||
idToChannel.put(channel.getObjectId(), channel.getChannelName()); | ||
} | ||
|
||
HashSet<String> stoppedChannels = new HashSet<>(); | ||
HashSet<String> unknownChannels = new HashSet<>(); | ||
HashSet<String> runningChannels = new HashSet<>(); | ||
|
||
|
||
HashMap<String, ChannelActivationStatus> activationMap = adminManager.getChannelActivationStatusHashMap(allChannels); | ||
for(String channel : activationMap.keySet()) { | ||
String name = idToChannel.get(channel); | ||
ChannelActivationStatus actStatus = activationMap.get(channel); | ||
if(actStatus != null) { | ||
ActivationState actState = actStatus.getActivationState(); | ||
if(actState == ActivationState.STOPPED) { | ||
stoppedChannels.add(name); | ||
} else if(actState == ActivationState.UNKNOWN) { | ||
unknownChannels.add(name); | ||
} else { | ||
runningChannels.add(name); | ||
} | ||
} | ||
} | ||
ClusterChannelStatusOverview overview = adminManager.getChannelStatusOverview(); | ||
|
||
int numberOfNodes = overview.getNodeCount(); | ||
|
||
for(int i=0;i<numberOfNodes;i++) { | ||
String nodeName = overview.getNodeName(i); | ||
HashSet<String> inactive = overview.getInactiveChannels(i); | ||
HashSet<String> inactive_Named = new HashSet<>(); | ||
for(String id : inactive) { | ||
String name = idToChannel.get(id); | ||
inactive_Named.add(name); | ||
} | ||
|
||
|
||
HashSet<String> withErrors = overview.getChannelsWithProcessingErrors(i); | ||
HashSet<String> withErrors_Named = new HashSet<>(); | ||
for(String id : withErrors) { | ||
String name = idToChannel.get(id); | ||
withErrors_Named.add(name); | ||
} | ||
|
||
|
||
HashSet<String> erronenous = overview.getErroneousChannels(i); | ||
HashSet<String> erronenous_Named = new HashSet<>(); | ||
for(String id : erronenous) { | ||
String name = idToChannel.get(id); | ||
erronenous_Named.add(name); | ||
} | ||
|
||
|
||
HashMap<String, Object> attributes = new HashMap<>(); | ||
attributes.put("NodeName", nodeName); | ||
attributes.put("Number Of Inactive Channels", inactive.size()); | ||
attributes.put("Number Of Channels With Errors", withErrors.size()); | ||
attributes.put("Number Of Erronous Channels", erronenous.size()); | ||
NewRelic.getAgent().getInsights().recordCustomEvent("ClusterChannelOverview", attributes); | ||
|
||
reportClusterNode(nodeName, inactive_Named, erronenous_Named, withErrors_Named, stoppedChannels, runningChannels,collectionTime); | ||
|
||
} | ||
|
||
|
||
|
||
|
||
|
||
} catch(Exception e) { | ||
NewRelic.getAgent().getLogger().log(Level.FINE, e, "Error executing Channel Monitoring"); | ||
} | ||
|
||
} | ||
|
||
private static void reportClusterNode(String nodeName, HashSet<String> inactives, HashSet<String> errornous, HashSet<String> withErrors, | ||
HashSet<String> stopped, Set<String> running, Date collectionTime) { | ||
StringBuffer sb = new StringBuffer(); | ||
|
||
sb.append("Collection Time: "); | ||
sb.append(collectionTime); | ||
sb.append(','); | ||
|
||
sb.append("Node Name: " + nodeName + ","); | ||
|
||
sb.append("Inactive Channels: ["); | ||
|
||
if(inactives != null && !inactives.isEmpty()) { | ||
int i = 0; | ||
int size = inactives.size(); | ||
|
||
for(String id : inactives) { | ||
sb.append(id); | ||
i++; | ||
if (i < size) { | ||
sb.append(','); | ||
} | ||
} | ||
} else { | ||
sb.append(" None Reported "); | ||
} | ||
sb.append("],"); | ||
|
||
sb.append("Errornous Channels: ["); | ||
|
||
if(errornous != null && !errornous.isEmpty()) { | ||
int i = 0; | ||
int size = errornous.size(); | ||
|
||
for(String id : errornous) { | ||
sb.append(id); | ||
i++; | ||
if(i < size) { | ||
sb.append(','); | ||
} | ||
} | ||
} else { | ||
sb.append(" None Reported "); | ||
} | ||
sb.append("],"); | ||
|
||
sb.append("With Errors Channels: ["); | ||
|
||
if(withErrors != null && !withErrors.isEmpty()) { | ||
int i = 0; | ||
int size = withErrors.size(); | ||
|
||
for(String id : withErrors) { | ||
sb.append(id); | ||
i++; | ||
if(i < size) { | ||
sb.append(','); | ||
} | ||
} | ||
} else { | ||
sb.append(" None Reported "); | ||
} | ||
sb.append("],"); | ||
|
||
sb.append("Stopped Channels: ["); | ||
|
||
if(stopped != null && !stopped.isEmpty()) { | ||
int i = 0; | ||
int size = stopped.size(); | ||
|
||
for(String id : stopped) { | ||
sb.append(id); | ||
i++; | ||
if(i < size) { | ||
sb.append(','); | ||
} | ||
} | ||
} else { | ||
sb.append(" None Reported "); | ||
} | ||
sb.append("],"); | ||
|
||
sb.append("Active Channels: ["); | ||
|
||
if(running != null && !running.isEmpty()) { | ||
int i = 0; | ||
int size = running.size(); | ||
|
||
for(String id : running) { | ||
sb.append(id); | ||
i++; | ||
if(i < size) { | ||
sb.append(','); | ||
} | ||
} | ||
} else { | ||
sb.append(" None Reported "); | ||
} | ||
sb.append("]"); | ||
|
||
ChannelMonitoringLogger.logToChannelMonitor(sb.toString()); | ||
} | ||
|
||
} |
Oops, something went wrong.