diff --git a/README-KeptnForDynatrace.md b/README-KeptnForDynatrace.md index 5ad25dd..95d835d 100644 --- a/README-KeptnForDynatrace.md +++ b/README-KeptnForDynatrace.md @@ -192,11 +192,8 @@ Payload: ```json { "specversion":"0.2", - "shkeptncontext":"{PID}", "type":"sh.keptn.events.problem", "source":"dynatrace", - "id":"{PID}", - "time":"", "contenttype":"application/json", "data": { "State":"{State}", diff --git a/files/jmeter/basiccheck_withdtmint.jmx b/files/jmeter/basiccheck_withdtmint.jmx index 8b02d9d..00c5a74 100644 --- a/files/jmeter/basiccheck_withdtmint.jmx +++ b/files/jmeter/basiccheck_withdtmint.jmx @@ -270,6 +270,11 @@ hm.add(new org.apache.jmeter.protocol.http.control.Header("x-dynatrace-test keptnProject=${KEPTN_PROJECT},keptnService=${KEPTN_SERVICE},keptnStage=${KEPTN_STAGE},keptnTestStrategy=${KEPTN_TESTSTRATEGY} = + + enabled + true + = + com.dynatrace.jmeter.plugins.MintBackendListener diff --git a/files/jmeter/basicload_withdtmint.jmx b/files/jmeter/basicload_withdtmint.jmx index 944311c..958a5a8 100644 --- a/files/jmeter/basicload_withdtmint.jmx +++ b/files/jmeter/basicload_withdtmint.jmx @@ -274,6 +274,11 @@ hm.add(new org.apache.jmeter.protocol.http.control.Header("x-dynatrace-test keptnProject=${KEPTN_PROJECT},keptnService=${KEPTN_SERVICE},keptnStage=${KEPTN_STAGE},keptnTestStrategy=${KEPTN_TESTSTRATEGY} = + + enabled + true + = + com.dynatrace.jmeter.plugins.MintBackendListener diff --git a/files/monaco/dashboard/qgdashboard.json b/files/monaco/dashboard/qgdashboard.json new file mode 100644 index 0000000..e5b2602 --- /dev/null +++ b/files/monaco/dashboard/qgdashboard.json @@ -0,0 +1,498 @@ +{ + "dashboardMetadata": { + "name": "{{ .name }}", + "shared": false, + "owner": "", + "sharingDetails": { + "linkShared": true, + "published": false + }, + "dashboardFilter": { + "timeframe": "" + } + }, + "tiles": [{ + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 646, + "left": 760, + "width": 418, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Worker Process Count (Avg);sli=proc_count;", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:tech.generic.processCount", + "aggregation": "AVG", + "type": "LINE", + "entityType": "PROCESS_GROUP_INSTANCE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 114, + "left": 0, + "width": 2052, + "height": 38 + }, + "tileFilter": {}, + "markdown": "KQG.Total.Pass=90%;KQG.Total.Warning=70%;KQG.Compare.WithScore=pass;KQG.Compare.Results=1;KQG.Compare.Function=avg" + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 190, + "left": 0, + "width": 380, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Response time (P95);sli=svc_rt_p95;pass=<+10%,<600", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:service.response.time", + "aggregation": "PERCENTILE", + "percentile": 95, + "type": "LINE", + "entityType": "SERVICE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 418, + "left": 0, + "width": 380, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Response time (P90);sli=svc_rt_p90;pass=<+10%,<550", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:service.response.time", + "aggregation": "PERCENTILE", + "percentile": 90, + "type": "LINE", + "entityType": "SERVICE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 646, + "left": 0, + "width": 380, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Response time (P50);sli=svc_rt_p50;pass=<+10%,<500", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:service.response.time", + "aggregation": "PERCENTILE", + "percentile": 50, + "type": "LINE", + "entityType": "SERVICE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 152, + "left": 0, + "width": 380, + "height": 38 + }, + "tileFilter": {}, + "markdown": "## Service Performance (SLI/SLO)" + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 152, + "left": 1178, + "width": 418, + "height": 38 + }, + "tileFilter": {}, + "markdown": "## Host-based (SLI/SLO)" + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 152, + "left": 760, + "width": 418, + "height": 38 + }, + "tileFilter": {}, + "markdown": "## Process Metrics (SLI/SLO)" + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 418, + "left": 760, + "width": 418, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Process Memory;sli=process_memory", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:tech.generic.mem.workingSetSize", + "aggregation": "AVG", + "type": "LINE", + "entityType": "PROCESS_GROUP_INSTANCE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 190, + "left": 760, + "width": 418, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Process CPU;sli=process_cpu;pass=<20;warning=<50;key=false", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:tech.generic.cpu.usage", + "aggregation": "AVG", + "type": "LINE", + "entityType": "PROCESS_GROUP_INSTANCE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 152, + "left": 380, + "width": 380, + "height": 38 + }, + "tileFilter": {}, + "markdown": "## Service Errors & Throughput (SLI/SLO)" + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 190, + "left": 380, + "width": 380, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Failure Rate (Avg);sli=svc_fr;pass=<+10%,<2", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:service.errors.server.rate", + "aggregation": "AVG", + "type": "LINE", + "entityType": "SERVICE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 418, + "left": 380, + "width": 380, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Throughput (per min);sli=svc_tp_min;pass=<+10%,<200", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:service.requestCount.total", + "aggregation": "NONE", + "type": "LINE", + "entityType": "SERVICE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "MINUTE" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 152, + "left": 1596, + "width": 456, + "height": 38 + }, + "tileFilter": {}, + "markdown": "## Test Transaction (SLI/SLO)" + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 190, + "left": 1178, + "width": 418, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Host CPU %;sli=host_cpu;pass=<20;warning=<50;key=false", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:host.cpu.usage", + "aggregation": "AVG", + "type": "LINE", + "entityType": "HOST", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 418, + "left": 1178, + "width": 418, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Host Memory used %;sli=host_mem;pass=<20;warning=<50;key=false", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:host.mem.usage", + "aggregation": "AVG", + "type": "LINE", + "entityType": "HOST", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 646, + "left": 1178, + "width": 418, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Host Disk Queue Length (max);sli=host_disk_queue;pass=<=0;warning=<1;key=false", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:host.disk.queueLength", + "aggregation": "MAX", + "type": "LINE", + "entityType": "HOST", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "TOTAL" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Custom chart", + "tileType": "CUSTOM_CHARTING", + "configured": true, + "bounds": { + "top": 646, + "left": 380, + "width": 380, + "height": 228 + }, + "tileFilter": {}, + "filterConfig": { + "type": "MIXED", + "customName": "Calls to backend services (per min);sli=svc2svc_calls;", + "defaultName": "Custom chart", + "chartConfig": { + "legendShown": true, + "type": "SINGLE_VALUE", + "series": [{ + "metric": "builtin:service.nonDbChildCallCount", + "aggregation": "NONE", + "type": "LINE", + "entityType": "SERVICE", + "dimensions": [], + "sortAscending": false, + "sortColumn": true, + "aggregationRate": "MINUTE" + }], + "resultMetadata": {} + }, + "filtersPerEntityType": {} + } + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 190, + "left": 1596, + "width": 456, + "height": 152 + }, + "tileFilter": {}, + "markdown": "## Extend with Test Transactions\n\n\nFollow the best practices around SRE-driven Performance Engineering as described in this [blog](https://www.dynatrace.com/news/blog/guide-to-automated-sre-driven-performance-engineering-analysis/)\n\nThis will allow you to add metrics per test or business transaction." + }, { + "name": "Markdown", + "tileType": "MARKDOWN", + "configured": true, + "bounds": { + "top": 0, + "left": 0, + "width": 2052, + "height": 114 + }, + "tileFilter": {}, + "markdown": "## Welcome to your first SLI/SLO-based Quality Gate Dashboard - view results in your [Keptn Bridge](${KEPTN_BRIDGE_PROJECT})\n \nThis default dashboard includes a set of base metrics (SLIs) that produce values in any Dynatrace deployment. \nUse this to make yourself familiar with defining your own SLIs (by adding more custom charts) and how to define SLOs (as part of the chart title) for every metric.\nThis default chart does not split by metric dimensions such as service, process, or host; however, splitting is supported by Keptn and is encouraged.\nFor more best practices on how to create these SLI/SLO dashboards please have a look at the [Dynatrace-SLI-Service readme](https://github.com/keptn-contrib/dynatrace-sli-service)." + }] + } \ No newline at end of file diff --git a/files/monaco/dashboard/qgdashboard.yaml b/files/monaco/dashboard/qgdashboard.yaml new file mode 100644 index 0000000..4111d26 --- /dev/null +++ b/files/monaco/dashboard/qgdashboard.yaml @@ -0,0 +1,5 @@ +config: + - qualitygatedashboard: "qgdashboard.json" + +qualitygatedashboard: + - name: "KQG;project={{ .Env.KEPTN_PROJECT }};service={{ .Env.KEPTN_SERVICE }};stage={{ .Env.KEPTN_STAGE }}" diff --git a/install-keptn-on-k3s.sh b/install-keptn-on-k3s.sh index def0798..a90443f 100755 --- a/install-keptn-on-k3s.sh +++ b/install-keptn-on-k3s.sh @@ -287,11 +287,12 @@ function install_keptn { --from-literal="KEPTN_API_TOKEN=$(get_keptn_token)" \ --from-literal="KEPTN_BRIDGE_URL=${PREFIX}://$KEPTN_DOMAIN/bridge" - apply_manifest_ns_keptn "https://raw.githubusercontent.com/keptn-contrib/dynatrace-service/0.10.1/deploy/service.yaml" - apply_manifest_ns_keptn "https://raw.githubusercontent.com/keptn-contrib/dynatrace-sli-service/0.7.2/deploy/service.yaml" - # apply_manifest_ns_keptn "https://raw.githubusercontent.com/keptn-contrib/dynatrace-sli-service/patch/release-0.7.1/deploy/service.yaml" + # Installing core dynatrace services + apply_manifest_ns_keptn "https://raw.githubusercontent.com/keptn-contrib/dynatrace-service/0.10.3/deploy/service.yaml" + apply_manifest_ns_keptn "https://raw.githubusercontent.com/keptn-contrib/dynatrace-sli-service/0.7.3/deploy/service.yaml" - apply_manifest_ns_keptn "https://raw.githubusercontent.com/keptn-sandbox/monaco-service/main/deploy/service.yaml" + # Installing monaco service + apply_manifest_ns_keptn "https://raw.githubusercontent.com/keptn-sandbox/monaco-service/release-0.2.1/deploy/service.yaml" # lets make Dynatrace the default SLI provider (feature enabled with lighthouse 0.7.2) "${K3SKUBECTL[@]}" create configmap lighthouse-config -n keptn --from-literal=sli-provider=dynatrace || true @@ -487,16 +488,6 @@ gitea_createGitRepo(){ } -# -# Creates a new Keptn project based on the shipyard. Also creates a gitea project and sets the upstream -# Parameters: -# 1: Keptn Project Name -# -function create_keptn_project { - keptn create project "${1}" --shipyard=keptn/${1}/shipyard.yaml -} - - function install_demo_dynatrace { write_progress "Installing Dynatrace Demo Projects" @@ -521,19 +512,22 @@ stages: EOF echo "Create Keptn Project: ${KEPTN_QG_PROJECT}" - # keptn create project "${KEPTN_QG_PROJECT}" --shipyard=keptn/${KEPTN_QG_PROJECT}/shipyard.yaml - create_keptn_project "${KEPTN_QG_PROJECT}" + keptn create project "${KEPTN_QG_PROJECT}" --shipyard=keptn/${KEPTN_QG_PROJECT}/shipyard.yaml echo "Create Keptn Service: ${KEPTN_QG_SERVICE}" keptn create service "${KEPTN_QG_SERVICE}" --project="${KEPTN_QG_PROJECT}" - echo "Create a Dynatrace SLI/SLO Dashboard for ${KEPTN_QG_PROJECT}.${KEPTN_QG_STAGE}.${KEPTN_QG_SERVICE}" - curl -fsSL -o /tmp/slo_sli_dashboard.json https://raw.githubusercontent.com/keptn-contrib/dynatrace-sli-service/master/dashboard/slo_sli_dashboard.json - sed -i "s/\${KEPTN_PROJECT}/${KEPTN_QG_PROJECT}/" /tmp/slo_sli_dashboard.json - sed -i "s/\${KEPTN_STAGE}/${KEPTN_QG_STAGE}/" /tmp/slo_sli_dashboard.json - sed -i "s/\${KEPTN_SERVICE}/${KEPTN_QG_SERVICE}/" /tmp/slo_sli_dashboard.json - sed -i "s/\${KEPTN_BRIDGE_PROJECT}/${KEPTN_BRIDGE_PROJECT_ESCAPED}/" /tmp/slo_sli_dashboard.json - curl -X POST ${DYNATRACE_ENDPOINT} -H "accept: application/json; charset=utf-8" -H "Authorization: Api-Token ${DYNATRACE_TOKEN}" -H "Content-Type: application/json; charset=utf-8" -d @/tmp/slo_sli_dashboard.json + echo "Adding Dynatrace SLI/SLO Dashboard Monaco Files for ${KEPTN_QG_PROJECT}.${KEPTN_QG_STAGE}.${KEPTN_QG_SERVICE}" + mkdir -p keptn/${KEPTN_QG_PROJECT}/monaco/projects/${KEPTN_QG_SERVICE}/dashboard + curl -fsSL -o keptn/${KEPTN_QG_PROJECT}/monaco/projects/${KEPTN_QG_SERVICE}/dashboard/qgdashboard.json https://raw.githubusercontent.com/keptn-sandbox/keptn-on-k3s/dynatrace-support/files/monaco/dashboard/qgdashboard.json + curl -fsSL -o keptn/${KEPTN_QG_PROJECT}/monaco/projects/${KEPTN_QG_SERVICE}/dashboard/qgdashboard.yaml https://raw.githubusercontent.com/keptn-sandbox/keptn-on-k3s/dynatrace-support/files/monaco/dashboard/qgdashboard.yaml + + # Replace one placeholder with the keptn bridge url + sed -i "s/\${KEPTN_BRIDGE_PROJECT}/${KEPTN_BRIDGE_PROJECT_ESCAPED}/" keptn/${KEPTN_QG_PROJECT}/monaco/projects/${KEPTN_QG_SERVICE}/dashboard/qgdashboard.json + + # upload monaco files + keptn add-resource --project="${KEPTN_QG_PROJECT}" --resource=keptn/${KEPTN_QG_PROJECT}/monaco/projects/${KEPTN_QG_SERVICE}/dashboard/qgdashboard.json --resourceUri=dynatrace/projects/${KEPTN_QG_SERVICE}/dashboard/qgdashboard.json + keptn add-resource --project="${KEPTN_QG_PROJECT}" --resource=keptn/${KEPTN_QG_PROJECT}/monaco/projects/${KEPTN_QG_SERVICE}/dashboard/qgdashboard.yaml --resourceUri=dynatrace/projects/${KEPTN_QG_SERVICE}/dashboard/qgdashboard.yaml echo "Add dynatrace.conf.yaml to enable SLI/SLO Dashboard query" cat > keptn/${KEPTN_QG_PROJECT}/dynatrace/dynatrace.conf.yaml << EOF @@ -552,8 +546,8 @@ attachRules: EOF keptn add-resource --project="${KEPTN_QG_PROJECT}" --resource=keptn/${KEPTN_QG_PROJECT}/dynatrace/dynatrace.conf.yaml --resourceUri=dynatrace/dynatrace.conf.yaml - # remove temporary file - rm /tmp/slo_sli_dashboard.json + + echo "Send keptn configuration change to apply config changes" echo "Run first Dynatrace Quality Gate" keptn send event start-evaluation --project="${KEPTN_QG_PROJECT}" --stage="${KEPTN_QG_STAGE}" --service="${KEPTN_QG_SERVICE}" @@ -571,8 +565,7 @@ stages: EOF echo "Create Keptn Project: ${KEPTN_PERFORMANCE_PROJECT}" - # keptn create project "${KEPTN_PERFORMANCE_PROJECT}" --shipyard=keptn/${KEPTN_PERFORMANCE_PROJECT}/shipyard.yaml - create_keptn_project "${KEPTN_PERFORMANCE_PROJECT}" + keptn create project "${KEPTN_PERFORMANCE_PROJECT}" --shipyard=keptn/${KEPTN_PERFORMANCE_PROJECT}/shipyard.yaml echo "Create Keptn Service: ${KEPTN_PERFORMANCE_SERVICE}" keptn create service "${KEPTN_PERFORMANCE_SERVICE}" --project="${KEPTN_PERFORMANCE_PROJECT}" @@ -639,8 +632,7 @@ stages: EOF echo "Create Keptn Project: ${KEPTN_REMEDIATION_PROJECT}" - # keptn create project "${KEPTN_REMEDIATION_PROJECT}" --shipyard=keptn/${KEPTN_REMEDIATION_PROJECT}/shipyard.yaml - create_keptn_project "${KEPTN_REMEDIATION_PROJECT}" + keptn create project "${KEPTN_REMEDIATION_PROJECT}" --shipyard=keptn/${KEPTN_REMEDIATION_PROJECT}/shipyard.yaml echo "Create Keptn Service: ${KEPTN_REMEDIATION_SERVICE}" keptn create service "${KEPTN_REMEDIATION_SERVICE}" --project="${KEPTN_REMEDIATION_PROJECT}"