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

Add Elastic APM demo #4

Merged
merged 10 commits into from
May 7, 2020
Merged
1 change: 1 addition & 0 deletions ocelot-meets-elastic-apm/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PROMETHEUS_PORT_CUSTOMER_SERVICE=9091
14 changes: 14 additions & 0 deletions ocelot-meets-elastic-apm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Ocelot meets Elastic APM

In this demo setup we instrument the Spring pet clinic application with inspectIT Ocelot agents and collect the monitoring data in Elasticsearch. In this configuration, Ocelot exports traces in Jaeger format and pushes them to Elastic's APM server via its Jaeger integration. Metrics are exposed in Prometheus/OpenMetrics format and collected by Elastic Metricbeat.

To run this Demo do the following:
- Make sure docker and docker-compose are installed on your system
- Start the demo with the following command:
```
docker-compose up -d
```
- Wait until the whole stack is running, this might take a couple of minutes
- Check the results in Kibana, depending on your Docker setup you may need to adjust the host for the following links to work:
- [APM and traces in Kibana](http://127.0.0.1:5601/app/apm#/services?rangeFrom=now-15m&rangeTo=now&refreshPaused=true&refreshInterval=0)
- [Ocelot metrics in Kibana](http://127.0.0.1:5601/app/infra#/infrastructure/metrics-explorer?metricsExplorer=(chartOptions:(stack:!f,type:line,yAxisMode:fromZero),options:(aggregation:rate,groupBy:prometheus.labels.service,metrics:!((aggregation:rate,color:color0,field:prometheus.metrics.http_in_responsetime_sum))),timerange:(from:now-15m,interval:%3E%3D10s,to:now)))
16 changes: 16 additions & 0 deletions ocelot-meets-elastic-apm/apm-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apm-server:
hosts: ["apm-server:8200"]
rum:
enabled: true
jaeger:
http:
enabled: true
host: "apm-server:14268"

output:
elasticsearch:
hosts: elasticsearch:9200

queue.mem.events: 4096

max_procs: 4
17 changes: 17 additions & 0 deletions ocelot-meets-elastic-apm/configuration-server/agent_mappings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
- name: "Gateway"
sources:
- "/gateway"
- "/all"
attributes:
service: "api-gateway"
- name: "Services"
sources:
- "/services"
- "/all"
attributes:
service: ".*-service"
- name: "Default Mapping"
sources:
- "/all"
attributes:
service: ".*"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
inspectit:
instrumentation:
data:
pet_type:
up-propagation: GLOBAL
down-propagation: GLOBAL

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
inspectit:
tags:
extra:
application: PetClinic
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# See https://github.com/inspectIT/inspectit-oce/blob/0.1.M1/inspectit-oce-core/src/main/resources/config/default.yml
# for all the configuration options.
inspectit:
metrics:
# root setting for the polling frequency of all metrics
# when a metrics has no frequency defined separately, this frequency will be used
frequency: 15s
config:
http:
frequency: 10s
logging:
debug: false # set to true to see more details in the agents logs
exporters:
tracing:
jaeger:
enabled: true
url: http://apm-server:14268/api/traces
service-name: ${inspectit.service-name}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
inspectit:
metrics:
definitions:
'[http/in/responsetime]':
views:
'[http/in/count]':
tags:
pet_type: true
'[http/in/responsetime/sum]':
tags:
pet_type: true

instrumentation:
rules:

http_server_servlet_api:
metrics:
'[http/in/responsetime]':
value: http_duration
data-tags:
pet_type: pet_type
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Parametrizes HTTP paths to be used in metrics
inspectit:
instrumentation:
rules:

parametrize_paths:
scopes:
servletapi_servlet_service: true
servletapi_filter_doFilter: true
httpurlconnection_getInputStream: true
apache_http_client_doExecute: true
httpurlconnection_connect: true
httpurlconnection_getOutputStream: true
entry:
parametrized_http_path:
action: string_replace_all
constant-input: { regex: "\\/\\d+(?=\\/|$)" , replacement: "/{id}"}
data-input: { string: http_raw_path}
only-if-not-null: http_raw_path
137 changes: 137 additions & 0 deletions ocelot-meets-elastic-apm/configuration-server/files/all/tracing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
inspectit:
tracing:
auto-tracing:
frequency: 10ms

instrumentation:
data:
get_input_stream_invoked:
down-propagation: JVM_LOCAL

actions:
string_concat_3:
input:
a: String
b: String
c: String
value: new StringBuilder(a).append(b).append(c).toString()
a_get_simple_method_name:
input:
_methodName: String
_class: Class
value: new StringBuilder(_class.getSimpleName()).append('.').append(_methodName).toString()

rules:
# use the existing rules from the default configuration but enable tracing
http_server_servlet_api:
tracing:
start-span: true
name: span_name
kind: SERVER
start-span-conditions:
only-if-true: http_is_entry
attributes:
'http.method': http_method
'http.status_code': http_status
pet-type: pet_type
auto-trace: true
entry:
span_name:
action: string_concat_3
data-input:
a: http_method
c: parametrized_http_path
constant-input:
b: " "

http_client_apache_client:
tracing:
start-span: true
name: span_name
kind: CLIENT
start-span-conditions:
only-if-true: http_is_entry
entry:
span_name:
action: string_concat_3
data-input:
a: http_method
c: parametrized_http_path
constant-input:
b: " "
span_type:
action: set
constant-input: {value: "web"}


httpurlconnection_tracing_start:
scopes:
httpurlconnection_connect: true
httpurlconnection_getOutputStream: true
tracing:
auto-trace: false
start-span: true
continue-span: span_obj
store-span: span_obj
end-span: false
name: span_name
kind: CLIENT
entry:
span_obj:
action: read_attachment_on_this
constant-input: {key: "span"}
http_raw_path:
action: httpurlconnection_get_path
http_method:
action: httpurlconnection_get_method
span_name:
action: string_concat_3
data-input:
a: http_method
c: parametrized_http_path
constant-input:
b: " "
post-entry:
span_obj:
action: replace_attachment_on_this
constant-input: {key: "span"}
data-input: {value: span_obj}

httpurlconnection_tracing_end:
scopes:
httpurlconnection_getInputStream: true
tracing:
auto-trace: false
start-span: true
continue-span: span_obj
store-span: span_obj
end-span: true
continue-span-conditions:
only-if-true: httpurlconn_get_is_entry
start-span-conditions:
only-if-true: httpurlconn_get_is_entry
name: span_name
kind: CLIENT
entry:
httpurlconn_get_is_entry:
action: test_and_set_this_marker
constant-input: {marker: "get_input_stream_invoked"}
span_obj:
action: read_attachment_on_this
constant-input: {key: "span"}
http_raw_path:
action: httpurlconnection_get_path
http_method:
action: httpurlconnection_get_method
span_name:
action: string_concat_3
data-input:
a: http_method
c: parametrized_http_path
constant-input:
b: " "
post-entry:
span_obj:
action: replace_attachment_on_this
constant-input: {key: "span"}
data-input: {value: span_obj}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
inspectit:
instrumentation:
scopes:
s_gateway_controller_validate_pet:
type:
name: org.springframework.samples.petclinic.api.boundary.web.ApiGatewayController
methods:
- name: validatePet
matcher-mode: STARTS_WITH

actions:
a_extract_pet_type:
imports:
- org.springframework.samples.petclinic.api.dto
input:
_arg0: PetDetails
value-body: |
return _arg0.getType().getName();

rules:
r_extract_pet_type:
scopes:
s_gateway_controller_validate_pet: true
tracing:
start-span: true
attributes:
pet-type: pet_type
resource: simple_method_name
entry:
pet_type:
action: a_extract_pet_type
simple_method_name:
action: a_get_simple_method_name

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
inspectit:
instrumentation:

scopes:
hsqldb_prepared_statement_execute:
type:
name: org.hsqldb.jdbc.JDBCPreparedStatement
methods:
- name: execute
matcher-mode: STARTS_WITH

data:
db_name: {down-propagation: NONE, is-tag: false}
sql: {down-propagation: NONE, is-tag: false}

actions:
# Extracts the SQL from a PreparedStatement for HSQLDB
hsqldb_prepared_statement_get_sql:
imports:
- org.hsqldb.jdbc
- java.lang.reflect
input:
_this: JDBCPreparedStatement
_class: Class
value-body: |
Field sqlField = _class.getDeclaredField("sql");
sqlField.setAccessible(true);
return sqlField.get(_this);

rules:
# We also trace JDBC calls including their target database
servicegraph_record_jdbc_calls:
tracing:
start-span: true
attributes:
'sql.database': db_name
dd_service: db_name
dd_type: span_type
dd_resource: sql
start-span-conditions:
only-if-true: servicegraph_is_entry
entry:
db_name:
action: get_jdbc_statement_connection_name
span_type:
action: set
constant-input: {value: "sql"}

# Extract the sql and add it to the trace
hsqldb_get_prep_statement_sql:
scopes:
hsqldb_prepared_statement_execute: true
entry:
sql:
action: hsqldb_prepared_statement_get_sql
Loading