Skip to content
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

Move EUM-server to separate repo #1

Merged
merged 9 commits into from
May 30, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/eumserver_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: EUM Server Tests

on:
push:
branches:
- main
pull_request:
branches:
- main
paths-ignore:
- 'README.md'
jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
container: openjdk:8-jdk
steps:
- uses: actions/checkout@v2
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: test
run: ./gradlew test
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.gradle
*build/
!gradle/wrapper/gradle-wrapper.jar
*.log
*.zip
*.swp
.DS_STORE

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
*/out/
/components/*/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

/working_directory/
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2019 Novatec Consulting GmbH

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
125 changes: 125 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# inspectit-ocelot-eum-server
This server provides Enduser Monitoring data by using the [OpenCensus](https://github.com/census-instrumentation/opencensus-java) toolkit.

## Metrics
The inspectit-ocelot server offers a backend for Javascript monitoring with [Boomerang](https://developer.akamai.com/tools/boomerang/docs/index.html).
Boomerang is a Javascript metrics agent, which is able to capture arbitrary customizable metrics.
By injecting the following snipped in your webpage, all measured metrics are sent to the inspectit-ocelot-eum-server:
```javascript
<script src="boomerang-1.0.0.min.js"></script>
<script src="plugins/rt.js"></script>
<!-- any other plugins you want to include -->
<script>
BOOMR.init({
beacon_url: "http://[inspectit-eum-server-url]:8080/beacon/"
});
</script>
```
Boomerang recommends to use an advanced injection, where the boomerang agent is loaded in an asynchronous way.
For further information, please visit the [Boomerang documentation](https://developer.akamai.com/tools/boomerang/docs/index.html).

If enabled, the server exposes the metrics by using the [Prometheus exporter](https://github.com/census-instrumentation/opencensus-java/tree/master/exporters/stats/prometheus).
A tutorial on how to install Prometheus can be found [here](https://opencensus.io/codelabs/prometheus/#0).

## Server Setup
Before starting the server, please build the server by cloning the repository and executing the following command or download the [latest release](https://github.com/inspectIT/inspectit-ocelot/releases).
```bash
$ ./gradlew build
```
Start the server with the following command:
```bash
$ java -jar inspectit-ocelot-eum-{version}.jar
```
By default, the server is starting with the port `8080`.
You can simply configure the port by using the Java property `-Dserver.port=[port]`:
```bash
$ java -Dserver.port=[port] -jar inspectit-ocelot-eum-0.0.1-SNAPSHOT.jar
```
Our server is delivered with a default configuration
supporting the metrics `t_page`, `t_done`, `rt.tstart`, `rt.nstart` and `rt.end` of the Boomerang plugin [RT](https://developer.akamai.com/tools/boomerang/docs/BOOMR.plugins.RT.html).
In order to provide a custom configuration, please set the Java property `-Dspring.config.location=file:[path-to-config]`:

```bash
$ java -Dserver.port=[port] -Dspring.config.location=file:[path-to-config] -jar inspectit-ocelot-eum-0.0.1-SNAPSHOT.jar
```

## Configuration
The configuration file defines the mapping between the concrete Boomerang metric and a OpenCensus metric, as the following sample configuration file shows:
```yaml
inspectit-eum-server:
definitions:
page_ready_time:
measure-type: LONG
beacon-field: t_page
unit: ms
views:
'[page_ready_time/SUM]': {aggregation: SUM}
'[page_ready_time/COUNT]': {aggregation: COUNT}
load_time:
measure-type: LONG
beacon-field: t_done
unit: ms
views:
'[load_time/SUM]': {aggregation: SUM}
'[load_time/COUNT]': {aggregation: COUNT}

start_timestamp:
measure-type: LONG
beacon-field: rt.tstart
unit: ms

navigation_start_timestamp:
measure-type: LONG
beacon-field: rt.nstart
unit: ms

end_timestamp:
measure-type: LONG
beacon-field: rt.end
unit: ms
views:
end_timestamp:
aggregation: LAST_VALUE
tags: {APPLICATION : true}
tags:
extra:
APPLICATION: my-application
beacon:
URL: u
OS: ua.plt
global:
- URL
- OS
- COUNTRY_CODE
exporters:
metrics:
prometheus:
enabled: true
host: localhost
port: 8888
```
##### Metrics Definition
A metric is defined through the following attributes:
* `name`: Defines the name of the metric. The name of the exposed view will have the used aggregation as suffix.
* `measure-type`: Can be either `LONG` or `DOUBLE`.
* `beacon-field`: The beacon key name, which is used as source of metric.
* `description`: Optional. Defines an additional description of the exposed metric.
* `unit`: The unit of the metric.
* `tag-keys`: Optional. Defines a list of tag keys, which are exposed with the current metric.
* `views`: A list of the views, which should be exposed. The aggregation can be either `SUM`, `COUNT`, `LAST_VALUE` or `HISTORGRAM`. For using `HISTOGRAM`, the field `bucket-boundaries` is mandatory.
* `bucket-boundaries`: Used for the `HISTOGRAM` aggregation, defines the bucket boundaries as list of Doubles.

##### Tags Definition
We distinguish between to different types of tags:
* `extra`- tags: Extra tags define tags, which are manually set in the configuration. The field `extra` holds a list of key-value mappings.
* `beacon`- tags: Beacon tags define tags, whose tag value is resolved by a beacon entry. The defined value of the `beacon` map will be resolved by using the provided beacon.
In order to provide selected tags to each measurement by default, tags can be defined as global. `global` holds a list of already defined tags, which will be then exposed for each measurement.

##### Automated Geolocation Detection
By using the tag `COUNTRY_CODE`, the geolocation of the requester is resolved by using the requester IP and the [GeoLite2 database](https://www.maxmind.com). If the IP cannot be resolved, the tag value will be empty.

##### Exporters
By now, the prometheus exporter is available. If `ènabled` is set to true, the exporter is exposes the metrics under
```bash
http://[host]:[port]/metrics
```
182 changes: 182 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
plugins {
id 'org.springframework.boot' version "${springboot_version}"
id 'com.palantir.docker' version "0.21.0"
id "org.cyclonedx.bom" version "1.5.0"
}

repositories {
mavenCentral()
maven {
name 'Nexus@NT'
url "https://repository.novatec-gmbh.de/content/repositories/3rd_party_libs/"
}
}

apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'

group = 'rocks.inspectit.ocelot'
sourceCompatibility = '1.8'

if (!project.hasProperty('buildVersion') || project.getProperty('buildVersion').empty) {
ext.buildVersion = 'SNAPSHOT'
}

version = "$buildVersion"

task downloadBoomerangjs() {
logger.info('Downloading Boomerangjs version {}.', boomerangVersion)
ext.dest = new File(buildDir, "boomerang-source-${boomerangVersion}.tgz")
outputs.files(ext.dest)
doLast {
def f = ext.dest
new URL("https://registry.npmjs.org/boomerangjs/-/boomerangjs-${boomerangVersion}.tgz")
.withInputStream { i -> f.withOutputStream { it << i } }
}
}

task deleteBoomerangjs(type: Delete) {
delete new File(project.buildDir, "boomerangjs-${boomerangVersion}")
}

task downloadAndExtractBoomerang(dependsOn: [deleteBoomerangjs, downloadBoomerangjs], type: Copy) {
from tarTree(downloadBoomerangjs.dest)
into new File(project.buildDir, "boomerangjs-${boomerangVersion}")
filter { line -> line.replaceAll('%boomerang_version%', "${boomerangVersion}") }
}

task generateVersionFile {
ext.versionFile = new File(project.buildDir, "eum-version.info")
doLast {
def currentDate = new Date().toString()
ext.versionFile.withWriter('UTF-8') { writer ->
writer << "$version\n$currentDate\n$boomerangVersion"
}
}
}

task downloadOpenTelemetryPlugin() {
ext.dest = new File(buildDir, "boomerang-opentelemetry.js")
outputs.files(ext.dest)
doLast {
def f = ext.dest
new URL("https://github.com/NovatecConsulting/boomerang-opentelemetry-plugin/releases/download/$openTelemetryVersion/boomerang-opentelemetry.js")
.withInputStream { i -> f.withOutputStream { it << i } }
}

}

bootJar {
dependsOn generateVersionFile
dependsOn downloadAndExtractBoomerang
dependsOn downloadOpenTelemetryPlugin

archivesBaseName = 'inspectit-ocelot-eum-server'
version = "${buildVersion}"

manifest {
attributes 'Start-Class': 'rocks.inspectit.oce.eum.server.EUMServerApplication'
}

// include version file
from generateVersionFile.versionFile

// include boomerang
from("$buildDir/boomerangjs-${boomerangVersion}/package") {
include "plugins/*.js"
include "boomerang.js"
into "static/boomerang"
}

//include boomerang opentelemetry
from("$buildDir") {
include "boomerang-opentelemetry.js"
into "static/boomerang"
}
}

cyclonedxBom {
includeConfigs += ["runtimeClasspath"]
}

test {
useJUnitPlatform()

testLogging {
exceptionFormat = 'full'
}
}

dependencies {
implementation(
//project(':inspectit-ocelot-config'),

"org.springframework.boot:spring-boot-starter-web",
'org.springframework.boot:spring-boot-starter-actuator',
"org.springframework.boot:spring-boot-starter-validation",
"org.springframework.security:spring-security-web:5.1.5.RELEASE",

// pin Prometheus client to 0.6.0 to prevent auto prefixing counter metrics with "_total"
// see: https://github.com/prometheus/client_java/issues/640, https://github.com/prometheus/client_java/pull/653
"io.prometheus:simpleclient:${prometheusClientVersion}",
"io.prometheus:simpleclient_common:${prometheusClientVersion}",
"io.prometheus:simpleclient_httpserver:${prometheusClientVersion}",

"io.opencensus:opencensus-api:${openCensusVersion}",
"io.opencensus:opencensus-impl:${openCensusVersion}",
"io.opencensus:opencensus-exporter-stats-prometheus:${openCensusVersion}",

"io.grpc:grpc-netty-shaded:1.36.1",
"io.grpc:grpc-protobuf:1.36.1",
"io.grpc:grpc-stub:1.36.1",
"io.opentelemetry:opentelemetry-proto:1.1.0-alpha",
"io.opentelemetry:opentelemetry-exporter-jaeger:1.1.0",
"io.opentelemetry:opentelemetry-sdk:1.1.0",

"com.google.protobuf:protobuf-java:3.15.7",
"com.google.protobuf:protobuf-java-util:3.15.7",

'com.maxmind.geoip2:geoip2:2.12.0',
'commons-net:commons-net:3.3',
"org.apache.commons:commons-lang3:3.+",
'org.apache.commons:commons-math3:3.6.1',
"org.influxdb:influxdb-java:2.15",
"rocks.inspectit:opencensus-influxdb-exporter:1.2",
)

compileOnly "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"

testImplementation(
//project(':inspectit-ocelot-config'),
"org.springframework.boot:spring-boot-starter-test",
"io.opencensus:opencensus-impl:${openCensusVersion}",
'org.apache.httpcomponents:httpclient:4.5.6',
'commons-io:commons-io:2.6',
"org.mockito:mockito-core:${mockitoVersion}",
'org.junit.jupiter:junit-jupiter-api:5.3.1',
'org.awaitility:awaitility:3.1.5',
'org.mockito:mockito-junit-jupiter:2.23.0',
'org.testcontainers:testcontainers:1.15.2',
'org.testcontainers:junit-jupiter:1.15.2'
)

testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.1"
}

task copyServerJar(type: Copy) {
dependsOn bootJar
from("${buildDir}/libs/inspectit-ocelot-eum-server-${version}.jar")
into("${buildDir}/docker-jar")
rename("inspectit-ocelot-eum-server-${version}\\.jar",
'inspectit-ocelot-eum-server.jar')
}

docker {
name "inspectit/inspectit-ocelot-eum-server"
tags "${version}"
dockerfile file('docker/Dockerfile')
files 'docker/entrypoint.sh', "$buildDir/docker-jar/inspectit-ocelot-eum-server.jar"
}
docker.dependsOn copyServerJar
4 changes: 4 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM openjdk:11-jre-slim
COPY inspectit-ocelot-eum-server.jar /
COPY entrypoint.sh /
ENTRYPOINT ["sh", "/entrypoint.sh"]
1 change: 1 addition & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exec java -Dserver.port=8085 -jar /inspectit-ocelot-eum-server.jar
Loading