-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Content: Observability for java applications #69
Conversation
This document leads through the steps to setup observability from the angle of a Java developer writing their own web application.
Hi @spinscale thanks for doing this! Before we start looking at the content, in terms of where the content will reside, I suggest the following:
|
thx for the hints, done! |
Hi @spinscale I completed a first-time pass edit on the tutorial. It still requires further edits before we move it from draft, however, you can now preview the doc. I will have a chat with the other Observability writers to ensure this is the structure we want in the final published doc. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a quick scan of this, and it looks really good. I'm excited to get this in the docs! As we discussed in the docs weekly, I think this format is fine and overlaps with the direction we want the docs to head in.
The corresponding code repo is at https://github.com/spinscale/observability-using-the-elastic-stack-java - however the reader should be able to build everything from scratch, not needing that repo, except for taking a short cut.
@spinscale, how would you feel about adding this project to an elastic repo? Maybe in the observability-docs repo under a new contrib directory? It'd be nice if the project lived here for us to update as necessary. With that being said, I understand if you want to keep it in your own repo.
Let me know when this is ready for a more thorough review, and I'll set aside a chunk of time to go through the entire tutorial.
A docs preview will be available soon: |
@elastic/obs-docs This is now ready for a review. @bmorelli25 I wasn't able to test the APM section, so it would be great if you could have a look at it. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is absolutely fantastic! I'm excited to see this level of detail added to the docs. My comments are mostly around usage of attributes to resolve doc paths. If I've made any typos in the paths, the CI will let you know. :-)
Very nicely done.
monitoring. Also, consider this just the beginning as the next step is | ||
to have synthetics that monitor the correct behavior of your | ||
application, for example, to ensure that your checkout process works all | ||
the time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a "What's next" section that points users to the next great thing they want to do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff!
I'm unable to make it past step 1.8. Please see this comment below. I get a FAILURE: Build failed with an exception.
#69 (comment). I tried googling for a couple hours but can't figure out what I'm doing wrong. I followed the tutorial line for line. I think it comes down to me not knowing what Set up a Gradle project
means. I tried with gradle init
, but perhaps that is not right. If I don't use gradle init
, I can't make it to 1.8.
. Run `./gradlew shadowJar`. This command creates a | ||
`build/libs/javalin-app-all.jar` file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't get past this step. I get the following error:
Brandons-MacBook-Pro-4 elastic-obs-java-app $ ./gradlew shadowJar
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/brandonmorelli/Documents/GitHub/elastic-obs-java-app/build.gradle' line: 17
* What went wrong:
A problem occurred evaluating root project 'javalin-app'.
> Could not find method application() for arguments [build_954lfwy4urhht8sn6t17frb29$_run_closure3@71d3bfa7] on root project 'javalin-app' of type org.gradle.api.Project.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you run ./gradlew --version
and paste the results here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the results when I run ./gradlew --version
Gradle 6.5.1
Build time: 2020-06-30 06:32:47 UTC
Revision: 66bc713f7169626a7f0134bf452abde51550ea0a
Kotlin: 1.3.72
Groovy: 2.5.11
Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM: 14.0.2 (Oracle Corporation 14.0.2+12-46)
OS: Mac OS X 10.14.5 x86_64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
------------------------------------------------------------
Gradle 6.5.1
------------------------------------------------------------
Build time: 2020-06-30 06:32:47 UTC
Revision: 66bc713f7169626a7f0134bf452abde51550ea0a
Kotlin: 1.3.72
Groovy: 2.5.11
Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM: 14.0.2 (Oracle Corporation 14.0.2+12-46)
OS: Mac OS X 10.15.6 x86_64
Looks to be the same as Eamonn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks good. Can you share your project somewhere so I can take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I copy your build.gradle
file from https://github.com/spinscale/observability-using-the-elastic-stack-java/blob/main/build.gradle, I'm able to run ./gradlew shadowJar
successfully. I think there is something missing from build.gradle
at this step, but I'm not sure what it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, here's what it looks like when following the tutorial (this fails)
plugins {
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'java'
}
repositories {
jcenter()
}
dependencies {
implementation 'io.javalin:javalin:3.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}
application {
mainClassName = 'de.spinscale.javalin.App'
}
test {
useJUnitPlatform()
}
And here's what it looks like after copying from your repo (this builds successfully)
plugins {
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'java'
// this helps identifying new versions with a single gradle call
id "com.github.ben-manes.versions" version '0.31.0'
}
repositories {
jcenter()
}
jar {
manifest {
attributes 'Main-Class': 'de.spinscale.javalin.App'
}
}
dependencies {
implementation 'io.javalin:javalin:3.10.0'
implementation 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.3'
implementation 'co.elastic.logging:log4j2-ecs-layout:0.5.0'
// metrics via micrometer
implementation 'io.micrometer:micrometer-core:1.5.4'
implementation 'io.micrometer:micrometer-registry-prometheus:1.5.4'
implementation 'org.apache.commons:commons-lang3:3.11'
// apm agent to implement custom transactions and spans
implementation 'co.elastic.apm:apm-agent-attach:1.17.0'
implementation "co.elastic.apm:apm-agent-api:1.17.0"
// http client
implementation 'org.apache.httpcomponents:fluent-hc:4.5.12'
testImplementation 'org.mockito:mockito-core:3.5.10'
testImplementation 'org.assertj:assertj-core:3.17.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}
test {
useJUnitPlatform()
}
// ensure the EcsLayout setting still functions properly
shadowJar {
transform(com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some trial and error, it's this part that causes my error:
application {
mainClassName = 'de.spinscale.javalin.App'
}
If I remove this from the tutorial's build.gradle
, it builds successfully:
plugins {
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'java'
}
repositories {
jcenter()
}
dependencies {
implementation 'io.javalin:javalin:3.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}
test {
useJUnitPlatform()
}
Can we remove these lines from the tutorial?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@spinscale Most of these comments/errors/suggestions are directed at you. It's getting late here, so I'm taking a break for now. I completed everything through Step 3 (Ingest Logs), and I'll pick up with metrics tomorrow.
. Run `./gradlew shadowJar`. This command creates a | ||
`build/libs/javalin-app-all.jar` file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I copy your build.gradle
file from https://github.com/spinscale/observability-using-the-elastic-stack-java/blob/main/build.gradle, I'm able to run ./gradlew shadowJar
successfully. I think there is something missing from build.gradle
at this step, but I'm not sure what it is.
. Run `./gradlew shadowJar`. This command creates a | ||
`build/libs/javalin-app-all.jar` file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, here's what it looks like when following the tutorial (this fails)
plugins {
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'java'
}
repositories {
jcenter()
}
dependencies {
implementation 'io.javalin:javalin:3.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}
application {
mainClassName = 'de.spinscale.javalin.App'
}
test {
useJUnitPlatform()
}
And here's what it looks like after copying from your repo (this builds successfully)
plugins {
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'java'
// this helps identifying new versions with a single gradle call
id "com.github.ben-manes.versions" version '0.31.0'
}
repositories {
jcenter()
}
jar {
manifest {
attributes 'Main-Class': 'de.spinscale.javalin.App'
}
}
dependencies {
implementation 'io.javalin:javalin:3.10.0'
implementation 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.3'
implementation 'co.elastic.logging:log4j2-ecs-layout:0.5.0'
// metrics via micrometer
implementation 'io.micrometer:micrometer-core:1.5.4'
implementation 'io.micrometer:micrometer-registry-prometheus:1.5.4'
implementation 'org.apache.commons:commons-lang3:3.11'
// apm agent to implement custom transactions and spans
implementation 'co.elastic.apm:apm-agent-attach:1.17.0'
implementation "co.elastic.apm:apm-agent-api:1.17.0"
// http client
implementation 'org.apache.httpcomponents:fluent-hc:4.5.12'
testImplementation 'org.mockito:mockito-core:3.5.10'
testImplementation 'org.assertj:assertj-core:3.17.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}
test {
useJUnitPlatform()
}
// ensure the EcsLayout setting still functions properly
shadowJar {
transform(com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer)
}
. Run `./gradlew shadowJar`. This command creates a | ||
`build/libs/javalin-app-all.jar` file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some trial and error, it's this part that causes my error:
application {
mainClassName = 'de.spinscale.javalin.App'
}
If I remove this from the tutorial's build.gradle
, it builds successfully:
plugins {
id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'java'
}
repositories {
jcenter()
}
dependencies {
implementation 'io.javalin:javalin:3.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}
test {
useJUnitPlatform()
}
Can we remove these lines from the tutorial?
+ | ||
[source,bash] | ||
---- | ||
java -jar build/libs/javalin-app-all.jar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this step I got the following error:
Brandons-MacBook-Pro-4 elastic-obs-java-app $ java -jar build/libs/javalin-app-all.jar
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
-------------------------------------------------------------------
-------------------------------------------------------------------
Missing dependency 'Slf4j simple'. Add the dependency.
pom.xml:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
build.gradle:
compile "org.slf4j:slf4j-simple:1.7.30"
Find the latest version here:
https://search.maven.org/search?q=g%3Aorg.slf4j+AND+a%3Aslf4j-simple
I was able to add compile 'org.slf4j:slf4j-simple:1.7.30'
to the dependencies section of build.gradle
, rerun ./gradlew shadowJar
, and then successfully run java -jar build/libs/javalin-app-all.jar
.
Do we need to mention this, or is my situation unique?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not need to do this after adding the org.apache.logging.log4j:log4j-slf4j18-impl:2.13.3
dependency. Did you do that?
Regarding your above comment, I fixed this by adding another line to the build.gradle
file.
Javalin app = Javalin.create(config -> { | ||
config.requestLogger((ctx, executionTimeMs) -> { | ||
String userAgent = ctx.userAgent() != null ? ctx.userAgent() : "-"; | ||
logger.info("{} {} {} {} \"{}\" {}", | ||
ctx.method(), ctx.req.getPathInfo(), ctx.res.getStatus(), | ||
ctx.req.getRemoteHost(), userAgent, executionTimeMs.longValue()); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code does not fix my "null" problem. I still see this:
2020-09-10T22:30:25,436-07:00 [INFO ] de.spinscale.javalin.App This is an informative logging message, user agent [null]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more comments for you, @spinscale! Got to the Custom transactions section this time. I'll finish up next week. This is looking great!
To improve security, add the username and the | ||
password to the keystore and refer it here as well. | ||
+ | ||
. Start {metricbeat} and verify that the Prometheus events are flowing into |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@EamonnTP We should add the start widget here
+ | ||
We did not configure any endpoint or API tokens yet. While the | ||
https://www.elastic.co/guide/en/apm/agent/java/current/setup-attach-api.html#setup-attach-api-configuration[documentation] | ||
recommends using the `src/main/resources/elasticapm.properties` file, I |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a tutorial, I agree.
I did another pass over this with many small fixes. One major change is to also add all the required imports in code snippets, to make it easier for others to understand those. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry this took so long to review. I'm stoked to finally get this merged!
One last thing regarding the accompanying code repository. I'm more than happy to move this under the elastic umbrella - I suppose it is better to have another |
My vote would be for something like an |
+1 to having a place for providing examples that support our tutorials. I also plan to provide some example data for the Kubernetes monitoring docs we'll be writing soon. I'm not sure if we should require users to have a GitHub account, though. I wonder how other doc teams are handling this question? I'd think a simple download link might be easier for some users. |
@dedemorton as that will become a public github repo, there is no need for an dedicated github account in order to clone it and play around with it I like the |
That's a good point, but wouldn't this still require users to set up the git client on their machine? For the Java tutorial, there's a pretty good chance that the target audience will know about git. But for some of the tutorials coming down the road (for example, tutorials targeted at analysts), I don't think we should expect them to clone repos or interact with git. I'm happy to shelve the conversation for now so you can get this thing done, but I think we need to revisit the question as a group and come up with an approach that works for other use cases that will require sample data or applications. EDITED: We should look at how other teams do this. I know the Logstash getting started docs provide a link to an archive that users can download: https://download.elastic.co/demos/logstash/gettingstarted/logstash-tutorial.log.gz. |
Sorry I missed the obs-docs sync this morning -- I imagine this was a topic of discussion. I think it's fine to treat tutorials targeted at analysts differently, for example, by hosting a download link with sample data. But for these kinds of tutorials, I think GitHub is the ideal choice. Some users wont want to download the entire sample app, but they may want to glance at certain source files as they build the project. GitHub repos also have the added benefit of showing up in Google and GitHub searches. |
I think the apm-contrib repo is a great example of how well a GitHub repo can work in this context. I don't want to post the traffic data publicly, but take a look (or I can share on slack if you don't have access). |
@bmorelli25 That's a good point; tailoring our delivery of sample code/applications to specific audiences makes sense. You've convinced me! |
@dedemorton your point regarding git, requiring it for non developers makes a lot of sense. Just to keep in mind: There is an option (with an always working link) to download the git repo as a zip file anytime under the This would allow users to always have the most recent download link of all your samples, while still enjoying the advantages of a versioned repo for all the folks creating the projects. Hope that helps! |
I just created the github repository at including the app at https://github.com/elastic/observability-contrib/tree/main/monitor-java-app and added the repo into the document. If you think this is ready from the docs team side, please go ahead and merge, as I have no idea in what branches I would need to do anything. Thank you @dedemorton, @EamonnTP and @bmorelli25 for all your help and edits, much appreciated! |
@spinscale Thank you for a great tutorial! |
* Add Content: Observability for java applications This document leads through the steps to setup observability from the angle of a Java developer writing their own web application. * Renaming according to review comments * First pass edit * Minor edits * Minor edits * First phase of review edits * Fixes based on review comments * review comments * update javalin version * review comments * improve snippets * minor overhaul * add transaction name setting to request logger * Improve setting transaction name * Add tab widgest * Minor edits * Add start widgets * Add mention of newly created github repository Co-authored-by: EamonnTP <Eamonn.Smith@elastic.co>
This document leads through the steps to setup observability from the
angle of a Java developer writing their own web application.
The corresponding code repo is at https://github.com/spinscale/observability-using-the-elastic-stack-java - however the reader should be able to build everything from scratch, not needing that repo, except for taking a short cut.
Note: As we are still figuring out, if this is the right format, let's not get into content corrections first, but make sure that everything is aligned the way we would like it to be :-)
HTML preview
https://observability-docs_69.docs-preview.app.elstc.co/guide/en/observability/master/monitor-java-app.html
Related issue
Closes #57