Skip to content

Commit

Permalink
Merge pull request #2990 from meiao/develop
Browse files Browse the repository at this point in the history
Java agent 7.1.0 release notes
  • Loading branch information
dbarnesbrownNR committed Jul 7, 2021
2 parents 5e3827b + b270785 commit 914b14c
Show file tree
Hide file tree
Showing 3 changed files with 281 additions and 7 deletions.
Expand Up @@ -244,6 +244,33 @@ The XML file format includes root and child nodes.
A method on the class to instrument. Pair this node with a `className` node. Also, the `method` node can have [children](#method-children).
</td>
</tr>

<tr>
<td>
`traceByReturnType`
</td>

<td>
The class name, including package, in the format used in bytecode, e.g. `Ljava/lang/String;`.

All methods that return an object of that class will be matched.
</td>
</tr>

<tr>
<td>
`traceLambda`
</td>

<td>
A boolean indicating whether to match lambdas.

The `traceLambda` node has the attributes:
- `includeNonstatic` - a boolean indicating whether to match non static methods (defaults to false);
- `pattern` - a string with the pattern to search for the lambda methods.
</td>
</tr>

</tbody>
</table>
</Collapser>
Expand Down Expand Up @@ -357,11 +384,11 @@ Here is a sample class and an XML file that could be used to instrument that cla
private Long getFirst(long[] times) {
return times[0];
}
private int getFirst() {
return 0;
}
public void printMaxRepeat(final long max) throws Exception {
Runnable myRunnable = new Runnable() {
public void run() {
Expand Down Expand Up @@ -396,7 +423,7 @@ Here is a sample class and an XML file that could be used to instrument that cla
name="customExtension" version="1.0">
<instrumentation metricPrefix="EXAMPLE">
<pointcut transactionStartPoint="true">
<!--class name is preceded by package name-->
<className>test.SampleTester</className>
<method>
Expand Down
Expand Up @@ -4,7 +4,7 @@ tags:
- Agents
- Java agent
- Custom instrumentation
metaDescription: Supplemental directions for instrumentating the New Relic Java agent with Scala applications.
metaDescription: Supplemental directions for instrumenting the New Relic Java agent with Scala applications.
redirects:
- /docs/java/scala-general-help
- /docs/java/scala-installation-for-java
Expand All @@ -16,11 +16,206 @@ The New Relic Java agent is [compatible with Scala](/docs/agents/java-agent/gett
For Heroku, see [Java agent with Scala on Heroku](/docs/agents/java-agent/heroku/java-agent-scala-heroku).
</Callout>

## Scala frameworks [#qiklinks]
## Scala frameworks [#frameworks]

If your [framework](/docs/agents/java-agent/getting-started/compatibility-requirements-java-agent#frameworks) is not natively supported by New Relic, or if you want to set up additional monitoring, [custom instrumentation](/docs/agents/java-agent/custom-instrumentation/java-custom-instrumentation) is a great way to dig deeper into your application.

## Instrument Scala with the Java agent API [#whats-next]
## Instrument Scala with the Scala API [#using-the-scala-api]

The New Relic Scala agent API lets you control, customize, and extend the
functionality of the APM Java agent using idiomatic Scala code. It can be used
alongside the [New Relic Java API](/docs/agents/java-agent/api-guides/guide-using-java-agent-api/)
as well as allow users to

- Create segments for synchronous and asynchronous anonymous functions
- Create segments for synchronous and asynchronous code blocks
- Create a transaction if one has not already been started

<Callout variant="important">
For best results when using the API, ensure that you have the latest Java agent
release. The New Relic Scala API requires Java agent 7.1.0 or higher.
</Callout>

### Use the Scala API

To access the API class add the following information to your Scala configuration file:

<CollapserGroup>
<Collapser
id="build-scala"
title={<><strong>Configure using the project/build.scala</strong> file</>}
>
Add the following line (replacing <var>S.V</var> with the Scala version
and <var>X.Y.Z</var> with the
[Java agent version](/docs/agents/java-agent/installation/update-java-agent#procedures)
you use) to the appDependencies method in your application's
`project/build.scala` file:

```
"com.newrelic.agent.java" % "newrelic-scala-api_<var>S.V</var>" % "<var>X.Y.Z</var>"
```
</Collapser>

<Collapser
id="build.sbt"
title={<><strong>Configure using the project/build.sbt</strong> file</>}
>
Add the following line (replacing <var>S.V</var> with the Scala version
and <var>X.Y.Z</var> with the[Java agent version](/docs/agents/java-agent/installation/update-java-agent#procedures)
you use) to your application's `project/build.sbt` file:

```
libraryDependencies += "com.newrelic.agent.java" % "newrelic-scala-api_<var>S.V</var>" % "<var>X.Y.Z</var>"
```
</Collapser>
</CollapserGroup>

Supported Scala versions are 2.10, 2.11, 2.12 and 2.13. Scala 3.0 users can use the 2.13 jar. The jar is deployed to Maven Central and it is also in the New Relic Java agent's installation zip file. You can call the API when the Java agent is not running. The underlying API methods are just stubs; the implementation is added when the Java agent is running.

### Segments

To create segment for a synchronous code block use `TraceOps.trace`. For
example:
```
import com.newrelic.scala.api.TraceOps.trace
trace("statement segment") {
val i = 1
val j = 2
println(i + j)
}
// trace can also be used as an expression
val x: Int = trace("expression segment") {
val i = 1
val j = 2
i + j
}
println(x) // 2
```

`trace` can also be used in Scala For comprehensions

```
import scala.concurrent.{ExecutionContext, Future}
import com.newrelic.scala.api.TraceOps.trace
// implicit execution
implicit val ec: ExecutionContext = ???
val x: Option[Int] = for {
one <- trace("segment one")(Option(1))
two <- trace("segment two")(Option(one + 1))
three <- trace("segment three")(Option(two + 1))
} yield three
println(x) // Some(3)
```

If you want to create segment for an asynchronous code block containing a Scala
Future use `TraceOps.asyncTrace`. This will ensure the timing for the segment
includes the time taken for the Future to complete.

In the example below segment time will be no less than 5 seconds due to the
delay created in the wrapped Future.
```
import scala.concurrent.{ExecutionContext, Future}
import com.newrelic.scala.api.TraceOps.asyncTrace
// implicit execution
implicit val ec: ExecutionContext = ???
val x: Future[Int] = asyncTrace("segment name")(Future {
Thread.sleep(5000)
1
})
x.foreach(println) // prints 1 on completion of Future
```

`asyncTrace` can also be used in Scala For comprehensions

```
import scala.concurrent.{ExecutionContext, Future}
import com.newrelic.scala.api.TraceOps.asyncTrace
// implicit execution
implicit val ec: ExecutionContext = ???
val x: Future[Int] = for {
one <- asyncTrace("segment one")(Future(1))
two <- asyncTrace("segment two")(Future(one + 1))
three <- asyncTrace("segment three")(Future(two + 1))
} yield three
x.foreach(println) // prints 3 on completion of Future
```

If you want to create segment for a synchronous anonymous function use
`TraceOps.traceFun`. For example:
```
import com.newrelic.scala.api.TraceOps.traceFun
val x: Option[Int] = Option(1)
.map(traceFun("statement segment")(i => i + 1))
println(x) //Some(2)
```

If you want to create segment for an asynchronous function that returns a Scala
Future use `TraceOps.asyncTrace`. This will ensure the timing for the segment
includes the time taken for the function to complete.

In the example below segment time will be no less than 5 seconds due to the
delay created in the wrapped Future.
```
import scala.concurrent.{ExecutionContext, Future}
import com.newrelic.scala.api.TraceOps.asyncTraceFun
// implicit execution
implicit val ec: ExecutionContext = ???
val x: Future[Int] = Future(1)
.flatMap(asyncTraceFun("statement segment")(i => Future(i + 1)))
x.foreach(println) // prints 2 on completion of Future
```

### Transactions

Transactions can be created using the `TraceOps.txn` method.
For example:

```
import com.newrelic.scala.api.TraceOps.txn
txn {
val i = 1
val j = 2
println(i + j)
}
```
`txn` can be used as a statement (as above) or as an expression
```
import com.newrelic.scala.api.TraceOps.txn
val i: Int = txn(1 + 2) //transaction created
println(i) // 3
```

`txn` can be used with any of the `TraceOp` methods to create segments. The
example below create a transaction with 3 segments.

```
import scala.concurrent.{ExecutionContext, Future}
import com.newrelic.scala.api.TraceOps.{txn, asyncTrace}
// implicit execution
implicit val ec: ExecutionContext = ???
val x: Future[Int] = txn(
for {
one <- asyncTrace("segment one")(Future(1))
two <- asyncTrace("segment two")(Future(one + 1))
three <- asyncTrace("segment three")(Future(two + 1))
} yield three
)
x.foreach(println) // prints 3 on completion of Future
```

## Instrument Scala with the Java agent API [#using-the-java-api]

Instrument Scala to use the New Relic API class or [annotations](/docs/agents/java-agent/java-agent-api/java-agent-api-instrument-using-annotation).

Expand Down Expand Up @@ -57,10 +252,17 @@ Instrument Scala to use the New Relic API class or [annotations](/docs/agents/ja
NewRelic.setTransactionName(null, "<var>/myTransaction</var>");
```

## More API functions [#other-api]
### More API functions [#other-api]

For more about the Java agent API and its functionality, see the [Java agent API introduction](/docs/agents/java-agent/custom-instrumentation/java-agent-api).

## Instrument Scala with XML instrumentation

XML instrumentation is available for any Scala application running with the Java
agent. It allows instrumentation to be added without any changes to the code.

For more information, see [Java instrumentation by XML](/docs/java/custom-instrumentation-by-xml/).

## Additional instrumentation

If you use Kamon, take a look at the New Relic [Kamon reporter](/docs/integrations/open-source-telemetry-integrations/open-source-telemetry-integration-list/kamon-reporter).
@@ -0,0 +1,45 @@
---
subject: Java agent
releaseDate: '2021-07-07'
version: 7.1.0
downloadLink: 'https://download.newrelic.com/newrelic/java-agent/newrelic-agent/7.1.0/'
---

### New features and improvements:

* Java instrumentation by XML new properties:
* traceLambda - to trace lambdas inside a method
* traceByReturnType - to trace all methods in a class that return a given type

These are compatible with Java and Scala. For more information, see
[Java instrumentation by XML](https://docs.newrelic.com/docs/agents/java-agent/custom-instrumentation/java-instrumentation-xml/).


* Scala APIs

New artifacts allow Scala code to be instrumented using a fluent Scala API
instead of the Java annotations. There are specific artifacts for versions
2.10, 2.11, 2.12, 2.13 of Scala. Scala 3.0 users can use the 2.13 artifact.

For more information, see [Scala instrumentation](https://docs.newrelic.com/docs/agents/java-agent/frameworks/scala-installation-java/).


* [Real-time profiling for Java using JFR metrics](/docs/agents/java-agent/features/real-time-profiling-java-using-jfr-metrics/)

This feature is now enabled by default.

**Notice:** this feature will cause an increase in the consumption of data.
The amount depends on the application. It can be disabled by adding the
following to the agent yaml config nested under the `common` stanza:
```
jfr:
enabled: false
```
For more information, see
[JFR core README](https://github.com/newrelic/newrelic-jfr-core/blob/main/README.md).


### Support statement:
* New Relic recommends that you upgrade the agent regularly to ensure that you're getting the latest features and
performance benefits. Additionally, older releases will no longer be supported when they reach
[end-of-life](https://docs.newrelic.com/docs/using-new-relic/cross-product-functions/install-configure/notification-changes-new-relic-saas-features-distributed-software/).

0 comments on commit 914b14c

Please sign in to comment.