-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:newrelic/newrelic-java-agent into g…
…ha-ubuntu-24
- Loading branch information
Showing
224 changed files
with
7,536 additions
and
1,095 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
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
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
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
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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
# The agent version. | ||
agentVersion=8.17.0 | ||
agentVersion=8.18.0 | ||
securityAgentVersion=1.6.0 | ||
|
||
newrelicDebug=false | ||
|
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
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
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
121 changes: 121 additions & 0 deletions
121
...rc/test/java/com/nr/agent/instrumentation/log4j2/layout/template/json/AgentUtilsTest.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,121 @@ | ||
/* | ||
* | ||
* * Copyright 2024 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
package com.nr.agent.instrumentation.log4j2.layout.template.json; | ||
|
||
import com.newrelic.agent.bridge.Agent; | ||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.api.agent.Config; | ||
import com.newrelic.api.agent.Logger; | ||
import org.apache.logging.log4j.core.LogEvent; | ||
import org.junit.After; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Random; | ||
import java.util.logging.Level; | ||
|
||
import static org.mockito.Mockito.*; | ||
import static org.junit.Assert.*; | ||
|
||
public class AgentUtilsTest { | ||
private static final String LOG_JSON_WITH_MESSAGE_FIELD_ESCAPED_QUOTE_COMMA = "{\"instant\" : {\"epochSecond\" : 1734983121,\"nanoOfSecond\" : 537701000},\"level\" : \"INFO\",\"loggerName\" : \"org.hibernate.validator.internal.util.Version\",\"message\" : \"info \\\"bar\\\",\",\"endOfBatch\" : true,\"loggerFqcn\" : \"org.hibernate.validator.internal.util.logging.Log_$logger\"}\n"; | ||
private static final String LOG_JSON_WITH_MESSAGE_LAST_FIELD_ESCAPED_QUOTE_BRACE = "{\"instant\": {\"epochSecond\": 1734983121,\"nanoOfSecond\": 537701000},\"level\": \"INFO\",\"loggerName\": \"org.hibernate.validator.internal.util.Version\",\"endOfBatch\": true,\"loggerFqcn\": \"org.hibernate.validator.internal.util.logging.Log_$logger\",\"message\": \"info \\\"bar\\\",\"}"; | ||
private static final String LOG_JSON_WITH_MESSAGE_FIELD = "{\"instant\" : {\"epochSecond\" : 1734983121,\"nanoOfSecond\" : 537701000},\"level\" : \"INFO\",\"loggerName\" : \"org.hibernate.validator.internal.util.Version\",\"message\" : \"normal msg text\",\"endOfBatch\" : true,\"loggerFqcn\" : \"org.hibernate.validator.internal.util.logging.Log_$logger\"}\n"; | ||
private static final String LOG_JSON_NO_MESSAGE_FIELD = "{\"instant\": {\"epochSecond\": 1734983121,\"nanoOfSecond\": 537701000},\"level\": \"INFO\",\"loggerName\": \"org.hibernate.validator.internal.util.Version\",\"endOfBatch\": true,\"loggerFqcn\": \"org.hibernate.validator.internal.util.logging.Log_$logger\",\"foobar\": \"info \\\"bar\\\",\"}"; | ||
|
||
private final Agent originalAgent = AgentBridge.getAgent(); | ||
private final Agent mockAgent = mock(Agent.class); | ||
private final Logger mockLogger = mock(Logger.class); | ||
private final Config mockConfig = mock(Config.class); | ||
|
||
private final LogEvent mockLockEvent = mock(LogEvent.class); | ||
|
||
@Before | ||
public void before() { | ||
AgentBridge.agent = mockAgent; | ||
when(mockAgent.getConfig()).thenReturn(mockConfig); | ||
when(mockAgent.getLogger()).thenReturn(mockLogger); | ||
when(mockLogger.isLoggable(Level.FINEST)).thenReturn(false); | ||
} | ||
|
||
@After | ||
public void after() { | ||
AgentBridge.agent = originalAgent; | ||
} | ||
|
||
@Test | ||
public void getIndexToModifyJson_withMessageField_findsProperIndex() { | ||
assertEquals(175, AgentUtils.getIndexToModifyJson(LOG_JSON_WITH_MESSAGE_FIELD_ESCAPED_QUOTE_COMMA)); | ||
assertEquals(262, AgentUtils.getIndexToModifyJson(LOG_JSON_WITH_MESSAGE_LAST_FIELD_ESCAPED_QUOTE_BRACE)); | ||
} | ||
|
||
@Test | ||
public void getIndexToModifyJson_withNoMessageField_returnsNegativeOne() { | ||
assertEquals(-1, AgentUtils.getIndexToModifyJson(LOG_JSON_NO_MESSAGE_FIELD)); | ||
} | ||
|
||
@Test | ||
public void writeLinkingMetadata_addsMetadataProperly() { | ||
when(mockConfig.getValue(anyString(), anyBoolean())).thenReturn(true); | ||
|
||
StringBuilder sb = new StringBuilder(LOG_JSON_WITH_MESSAGE_FIELD_ESCAPED_QUOTE_COMMA); | ||
AgentUtils.writeLinkingMetadata(mockLockEvent, sb); | ||
assertTrue(sb.toString().contains("\"message\" : \"info \\\"bar\\\", NR-LINKING|\"")); | ||
|
||
sb = new StringBuilder(LOG_JSON_WITH_MESSAGE_LAST_FIELD_ESCAPED_QUOTE_BRACE); | ||
AgentUtils.writeLinkingMetadata(mockLockEvent, sb); | ||
assertTrue(sb.toString().contains("\"message\": \"info \\\"bar\\\", NR-LINKING|\"}")); | ||
|
||
sb = new StringBuilder(LOG_JSON_WITH_MESSAGE_FIELD); | ||
AgentUtils.writeLinkingMetadata(mockLockEvent, sb); | ||
assertTrue(sb.toString().contains("\"message\" : \"normal msg text NR-LINKING|\"")); | ||
|
||
sb = new StringBuilder(LOG_JSON_NO_MESSAGE_FIELD); | ||
AgentUtils.writeLinkingMetadata(mockLockEvent, sb); | ||
assertFalse(sb.toString().contains("NR-LINKING|")); | ||
|
||
} | ||
|
||
// Leaving these next two methods here in case anyone wants to run a simple performance test of the regex matching. | ||
// Simple uncomment the @Test annotation and run like a normal test. | ||
//@Test | ||
public void simplePerfTest() { | ||
final String JSON_TEMPLATE = "{\"instant\" : {\"epochSecond\" : 1734983121,\"nanoOfSecond\" : 537701000},\"level\" : \"INFO\",\"loggerName\" : \"org.hibernate.validator.internal.util.Version\",\"message\" : \"{MSG_VAL}\",\"endOfBatch\" : true,\"loggerFqcn\" : \"org.hibernate.validator.internal.util.logging.Log_$logger\"}\n"; | ||
final String ESCAPED_QUOTE_COMMA = "info \\\"bar\\\","; | ||
final int LOOP_SIZE = 1000000; | ||
Random random = new Random(); | ||
List<String> randomStringList = new ArrayList<>(); | ||
|
||
// Gen up a list of random Strings so we don't spend cycles in the actual timing loop creating them | ||
for (int i=0; i<LOOP_SIZE; i++) { | ||
randomStringList.add(generateRandomStr(10)); | ||
} | ||
|
||
long start = System.currentTimeMillis(); | ||
for (int i=0; i<LOOP_SIZE; i++) { | ||
if (random.nextInt(101) >= 90) { | ||
AgentUtils.getIndexToModifyJson(JSON_TEMPLATE.replace("{MSG_VAL}", ESCAPED_QUOTE_COMMA)); | ||
} else { | ||
AgentUtils.getIndexToModifyJson(JSON_TEMPLATE.replace("{MSG_VAL}", randomStringList.get(i))); | ||
} | ||
} | ||
System.out.println("Time ---> " + (System.currentTimeMillis() - start)); | ||
} | ||
|
||
private static String generateRandomStr(int length) { | ||
String CANDIDATE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
StringBuilder sb = new StringBuilder(); | ||
Random random = new Random(); | ||
for (int i = 0; i < length; i ++) { | ||
sb.append(CANDIDATE_CHARS.charAt(random.nextInt(26))); | ||
} | ||
|
||
return sb.toString(); | ||
} | ||
} |
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,18 @@ | ||
dependencies { | ||
implementation(project(":agent-bridge")) | ||
implementation("org.apache.struts:struts2-core:6.7.0") | ||
} | ||
|
||
jar { | ||
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.apache-struts-6.7.0', | ||
'Implementation-Title-Alias': 'apache-struts' } | ||
} | ||
|
||
verifyInstrumentation { | ||
passesOnly 'org.apache.struts:struts2-core:[6.7.0,)' | ||
} | ||
|
||
site { | ||
title 'Struts' | ||
type 'Framework' | ||
} |
24 changes: 24 additions & 0 deletions
24
...ion/apache-struts-6.7.0/src/main/java/org/apache/struts2/ActionProxy_Instrumentation.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,24 @@ | ||
package org.apache.struts2; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.agent.bridge.Transaction; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.TransactionNamePriority; | ||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.apache.struts2.ActionProxy") | ||
public abstract class ActionProxy_Instrumentation { | ||
@Trace | ||
public String execute() throws Exception { | ||
Transaction transaction = AgentBridge.getAgent().getTransaction(false); | ||
if (transaction != null) { | ||
transaction.setTransactionName(TransactionNamePriority.FRAMEWORK_HIGH, true, "StrutsAction", getActionName()); | ||
} | ||
|
||
return Weaver.callOriginal(); | ||
} | ||
|
||
public abstract String getActionName(); | ||
} |
22 changes: 22 additions & 0 deletions
22
...n/apache-struts-6.7.0/src/main/java/org/apache/struts2/result/Result_Instrumentation.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,22 @@ | ||
package org.apache.struts2.result; | ||
|
||
import com.newrelic.api.agent.NewRelic; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.TracedMethod; | ||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
import org.apache.struts2.ActionInvocation; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.apache.struts2.result.Result") | ||
public class Result_Instrumentation { | ||
@Trace | ||
public void execute(ActionInvocation invocation) throws Exception { | ||
TracedMethod tracedMethod = NewRelic.getAgent().getTracedMethod(); | ||
if (tracedMethod != null && invocation != null) { | ||
tracedMethod.setMetricName("StrutsResult", invocation.getAction().getClass().getName()); | ||
} | ||
|
||
Weaver.callOriginal(); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
...ation/apache-struts-6.7.0/src/test/java/com/nr/agent/instrumentation/ActionProxyTest.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,36 @@ | ||
package com.nr.agent.instrumentation; | ||
|
||
import com.newrelic.agent.introspec.InstrumentationTestConfig; | ||
import com.newrelic.agent.introspec.InstrumentationTestRunner; | ||
import com.newrelic.agent.introspec.Introspector; | ||
import com.opensymphony.xwork2.ActionInvocation; | ||
import com.opensymphony.xwork2.DefaultActionProxy; | ||
import com.opensymphony.xwork2.mock.MockActionInvocation; | ||
import org.apache.struts2.ActionProxy; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
||
@RunWith(InstrumentationTestRunner.class) | ||
@InstrumentationTestConfig(includePrefixes = { "org.apache.struts2" }) | ||
public class ActionProxyTest { | ||
@Test | ||
public void execute_setsTxnName() throws Exception { | ||
ActionProxy proxy = new ActionProxyTest.SampleStruts2ActionProxy(new MockActionInvocation(), "namespace", "actionName", "method", true, true); | ||
|
||
StrutsSampleApp.executeOnActionProxy(proxy); | ||
|
||
Introspector introspector = InstrumentationTestRunner.getIntrospector(); | ||
Assert.assertTrue(introspector.getTransactionNames().contains("OtherTransaction/StrutsAction/actionName")); | ||
} | ||
|
||
public static class SampleStruts2ActionProxy extends DefaultActionProxy { | ||
|
||
public SampleStruts2ActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, | ||
boolean cleanupContext) { | ||
super(inv, namespace, actionName, methodName, executeResult, cleanupContext); | ||
} | ||
|
||
|
||
} | ||
} |
Oops, something went wrong.