blob: 605547965c834600b9d28d48de2ffadb30aaf98a [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Creating A Telemetry Plug-in :: Eclipse Che Documentation</title>
<link rel="canonical" href="https://www.eclipse.org/che/docs/che-7/extensions/creating-a-telemetry-plugin/">
<meta name="keywords" content="extensions, telemetry">
<meta name="generator" content="Antora 2.3.4">
<link rel="stylesheet" href="../../../_/css/site.css">
<link rel="stylesheet" href="../../../_/css/extra.css">
<link rel="stylesheet" href="../../../_/font-awesome-4.7.0/css/font-awesome.min.css">
<link rel="icon" href="../../../favicon.ico" type="image/x-icon">
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-37306001-2"></script>
<script>function gtag(){dataLayer.push(arguments)};window.dataLayer=window.dataLayer||[];gtag('js',new Date());gtag('config','UA-37306001-2')</script>
<script>var uiRootPath = '../../../_'</script>
</head>
<body class="article">
<header class="header" role="banner">
<nav class="navbar">
<div class="navbar-brand">
<div class="navbar-item">
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
<img src="../../../_/img/icon-eclipse-che.svg" class="navbar-logo" alt="Eclipse Che logo">
<a href="https://www.eclipse.org/che/docs">Eclipse Che Documentation</a>
</div>
</div>
<div id="topbar-nav" class="navbar-menu">
<div class="navbar-end">
<div class="navbar-item hide-for-print">
<script async src="https://cse.google.com/cse.js?cx=002898025167115630151:gnr5edrg2eo"></script>
<div class="gcse-searchbox" enableAutoComplete="true"></div>
</div>
<a class="navbar-item" href="https://www.eclipse.org/che/docs">Home</a>
<a class="navbar-item" href="https://che.eclipse.org/">Blog</a>
<a class="navbar-item" href="https://github.com/eclipse/che">Source Code</a>
</div>
</div>
</nav>
<div class="gcse-searchresults"></div>
</header><div class="body">
<div class="nav-container" data-component="che-7" data-version="master">
<aside class="nav">
<div class="panels">
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../../overview/introduction-to-eclipse-che/">Documentation</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../overview/introduction-to-eclipse-che/">Introduction to Che</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../overview/che-architecture/">Che architecture</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../hosted-che/hosted-che/">Eclipse Che hosted by Red Hat</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="0">
<button class="nav-item-toggle"></button>
<span class="nav-text">End-user Guide</span>
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/navigating-che/">Navigating Che</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/navigating-che-using-the-dashboard/">Navigating Che: dashboard</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/importing-certificates-to-browsers/">Importing certificates to browsers</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/accessing-che-from-openshift-developer-perspective/">Navigating Che from OpenShift Developer Perspective</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/che-theia-ide-basics/">Che-Theia IDE basics</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/defining-custom-commands-for-che-theia/">Defining custom commands for Che-Theia</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/version-control/">Version Control</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/che-theia-troubleshooting/">Che-Theia Troubleshooting</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/differences-in-how-che-theia-webview-works-on-a-single-host-mode-comparing-to-a-multi-host-mode/">Differences in how Che-Theia Webview works on a single-host mode comparing to a multi-host mode</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/workspaces-overview/">Using developer workspaces</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/creating-a-workspace-from-code-sample/">Creating a workspace from code sample</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/creating-a-workspace-from-remote-devfile/">Creating a workspace from a remote devfile using the dashboard</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/creating-a-workspace-from-local-devfile-using-chectl/">Creating a workspace from local devfile using chectl</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/creating-a-workspace-by-importing-the-source-code-of-a-project/">Creating a workspace by importing the source code of a project</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/configuring-a-workspace-with-dashboard/">Configuring a workspace</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/running-a-workspace-with-dashboard/">Running a workspace</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/importing-kubernetes-applications-into-a-workspace/">Importing Kubernetes applications into a workspace</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/remotely-accessing-workspaces/">Remotely accessing workspaces</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/mounting-a-secret-as-a-file-or-an-environment-variable-into-a-workspace-container/">Mounting a secret as a file or an environment variable into a workspace container</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/authenticating-on-scm-server-with-a-personal-access-token/">Authenticating on SCM Server with a personal access token</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/authoring-devfiles/">Authoring devfiles</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/authoring-devfiles-version-1/">Authoring devfiles version 1</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/authoring-devfiles-version-2/">Authoring devfiles version 2</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/customizing-developer-environments/">Customizing developer environments</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/what-is-a-che-theia-plug-in/">What is a Che-Theia plug-in</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/adding-a-vs-code-extension-to-a-workspace/">Adding a VS Code extension to a workspace</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/adding-a-vs-code-extension-to-the-che-plugin-registry/">Adding a VS Code extension to the Che plug-ins registry</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/publishing-metadata-for-a-vs-code-extension/">Publishing a VS Code extension</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/testing-a-visual-studio-code-extension-in-che/">Testing a VS Code extension in Che</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/using-alternative-ides-in-che/">Using alternative IDEs in Che</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/support-for-jetbrains-ides/">JetBrains IDEs</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../end-user-guide/using-jetbrains-intellij-idea-community-edition/">Using IntelliJ Idea Community Edition</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../end-user-guide/using-jetbrains-intellij-idea-ultimate-edition/">Using IntelliJ Idea Ultimate Edition</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../end-user-guide/configuring-an-existing-workspace-to-use-intellij-idea/">Configuring an existing workspace to use IntelliJ IDEA</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../end-user-guide/using-jetbrains-webstorm/">Using WebStorm</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../end-user-guide/provisioning-jetbrains-activation-code-for-offline-use/">Provisioning activation code for offline use</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../end-user-guide/support-for-theia-based-ides/">Theia-based IDEs</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/adding-tools-to-che-after-creating-a-workspace/">Adding tools to Che after creating a workspace</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/using-private-container-registries/">Using private container registries</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/using-artifact-repositories-in-a-restricted-environment/">Using artifact repositories in a restricted environment</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/using-maven-artifact-repositories/">Using Maven artifact repositories</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/using-gradle-artifact-repositories/">Using Gradle artifact repositories</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/using-python-artifact-repositories/">Using Python artifact repositories</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/using-go-artifact-repositories/">Using Go artifact repositories</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/using-nuget-artifact-repositories/">Using NuGet artifact repositories</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/using-npm-artifact-repositories/">Using npm artifact repositories</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../end-user-guide/troubleshooting-che/">Troubleshooting Che</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/viewing-che-workspaces-logs/">Viewing Che workspaces logs</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/investigating-failures-at-a-workspace-start-using-the-verbose-mode/">Troubleshooting workspace start failures</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/troubleshooting-slow-workspaces/">Troubleshooting slow workspaces</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../end-user-guide/troubleshooting-network-problems/">Troubleshooting network problems</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="0">
<button class="nav-item-toggle"></button>
<span class="nav-text">Installation Guide</span>
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../installation-guide/supported-platforms/">Supported platforms</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../installation-guide/configuring-the-che-installation/">Configuring the Che installation</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../installation-guide/installing-che/">Installing Che</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../installation-guide/installing-che-in-cloud/">Installing Che in cloud</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-openshift-4-using-operatorhub/">Installing Che on OpenShift 4 using OperatorHub</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-openshift-4-using-cli/">Installing Che on OpenShift 4 using CLI</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-openshift-3-using-the-operator/">Installing Che on OpenShift 3</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-kubespray/">Installing Che on Kubespray</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-aws/">Installing Che on AWS</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-google-cloud-platform/">Installing Che on Google Cloud</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-microsoft-azure/">Installing Che on Microsoft Azure</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../installation-guide/installing-che-locally/">Installing Che locally</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-codeready-containers/">Installing Che on CodeReady Containers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-docker-desktop/">Installing Che on Docker Desktop</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-minikube/">Installing Che on Minikube</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-minishift/">Installing Che on Minishift</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../installation-guide/installing-che-on-kind/">Installing Che on Kind</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/using-the-chectl-management-tool/">Using the chectl management tool</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/installing-che-in-a-restricted-environment/">Installing Che in restricted environment</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../installation-guide/advanced-configuration/">Advanced configuration</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/advanced-configuration-options-for-the-che-server-component/">Advanced configuration options for Che server</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-namespace-strategies/">Configuring workspace target namespace</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-storage-strategies/">Configuring storage strategies</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-storage-types/">Configuring storage types</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-the-number-of-workspaces-that-a-user-can-run/">Configuring the number of workspaces that a user can run</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-the-number-of-workspaces-that-a-user-can-create/">Configuring the number of workspaces that a user can create</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-workspace-exposure-strategies/">Configuring workspace exposure strategies</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-workspaces-nodeselector/">Configuring workspaces nodeSelector</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-che-hostname/">Configuring Che hostname</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-ingresses/">Configuring Kubernetes Ingress</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/configuring-routes/">Configuring OpenShift Route</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/deploying-che-with-support-for-git-repositories-with-self-signed-certificates/">Deploying Che with support for Git repositories with self-signed certificates</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/installing-che-using-storage-classes/">Installing Che using storage classes</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/importing-untrusted-tls-certificates/">Importing untrusted TLS certificates to Che</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/switching-between-external-and-internal-communication/">Switching between external and internal ways in inter-component communication</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/setting-up-the-keycloak-che-username-readonly-theme-for-the-eclipse-che-login-page/">Setting up the Keycloak che-username-readonly theme for the Eclipse Che login page</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/mounting-a-secret-as-a-file-or-an-environment-variable-into-a-container/">Mounting a Secret or a ConfigMap as a file or an environment variable into a Eclipse&#160;Che container</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/enabling-dev-workspace-engine/">Enabling Dev Workspace engine</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../installation-guide/upgrading-che/">Upgrading Che</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/upgrading-che-using-operatorhub/">Upgrading Che using OperatorHub</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/upgrading-che-using-the-cli-management-tool/">Upgrading Che using the CLI management tool</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/upgrading-che-using-the-cli-management-tool-in-restricted-environment/">Upgrading Che in restricted environment</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/upgrading-che-namespace-strategies-other-than-per-user/">Updating Che namespace strategies other than 'per user'</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../installation-guide/uninstalling-che/">Uninstalling Che</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/uninstalling-che-after-operatorhub-installation-using-openshift-web-console/">Using the OpenShift web console</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/uninstalling-che-after-operatorhub-installation-using-openshift-cli/">Using OpenShift CLI</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../installation-guide/uninstalling-che-after-chectl-installation/">Using chectl</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="0">
<button class="nav-item-toggle"></button>
<span class="nav-text">Administration Guide</span>
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../administration-guide/che-architecture-overview/">Che architecture</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/che-workspace-controller/">Che workspace controller</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/che-workspaces-architecture/">Che workspaces architecture</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../administration-guide/calculating-che-resource-requirements/">Calculating Che resource requirements</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../administration-guide/customizing-the-registries/">Customizing the registries</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/building-custom-registry-images/">Building custom registry images</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/running-custom-registries/">Running custom registries</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../administration-guide/retrieving-che-logs/">Retrieving Che logs</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/configuring-server-logging/">Configuring server logging</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/viewing-kubernetes-events/">Accessing Kubernetes events on OpenShift</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/viewing-operator-events/">Viewing the Operator events on OpenShift</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/viewing-che-server-logs/">Viewing Che server logs</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/viewing-external-service-logs/">Viewing external service logs</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/viewing-plug-in-broker-logs/">Viewing Plug-in broker logs</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/collecting-logs-using-chectl/">Collecting logs using chectl</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../administration-guide/monitoring-che/">Monitoring Che</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../administration-guide/tracing-che/">Tracing Che</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../administration-guide/backup-and-disaster-recovery/">Backup and disaster recovery</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/external-database-setup/">External database setup</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/persistent-volumes-backups/">Persistent Volumes backups</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../administration-guide/caching-images-for-faster-workspace-start/">Caching images for faster workspace start</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/defining-the-list-of-images-to-pull/">Defining the list of images</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/defining-the-memory-parameters-for-the-image-puller/">Defining the memory settings</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/installing-image-puller-using-che-operator/">Installing using the Che Operator</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/installing-image-puller-on-kubernetes-using-the-image-puller-operator/">Installing using the Kubernetes Image Puller Operator</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/installing-image-puller-on-openshift-using-operatorhub/">Installing on OpenShift 4</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/installing-image-puller-on-openshift-using-openshift-templates/">Installing on OpenShift 3</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/installing-image-puller-on-kubernetes-using-helm/">Installing using Helm</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../administration-guide/managing-identities-and-authorizations/">Managing identities and authorizations</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/authenticating-users/">Authenticating users</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/authorizing-users/">Authorizing users</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/configuring-authorization/">Configuring authorization</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/configuring-openshift-oauth/">Configuring OpenShift OAuth</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../administration-guide/removing-user-data/">Removing user data</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="0">
<button class="nav-item-toggle"></button>
<span class="nav-text">Contributor Guide</span>
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../contributor-guide/branding-che-theia/">Branding Che-Theia</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../contributor-guide/developing-che-theia-plug-ins/">Developing Che-Theia plug-ins</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../contributor-guide/testing-che-theia-plug-ins/">Testing Che-Theia plug-ins</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../contributor-guide/publishing-che-theia-plug-ins/">Publishing Che-Theia plug-ins</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../contributor-guide/adding-support-for-a-new-language/">Adding support for a new language</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../contributor-guide/adding-support-for-a-new-debugger/">Adding support for a new debugger</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../contributor-guide/che-extensibility-reference/">Che extensibility reference</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../contributor-guide/che-extension-points/">Che extension points</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../contributor-guide/che-theia-plug-in-api/">Che-Theia plug-in API</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../contributor-guide/debug-adapter-protocol/">Debug Adapter Protocol</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../contributor-guide/language-server-protocol/">Language Server Protocol</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="0">
<button class="nav-item-toggle"></button>
<span class="nav-text">Extensions</span>
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../eclipse-che4z/">eclipse-che4z.adoc</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../openshift-connector-overview/">OpenShift Connector</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../features-of-openshift-connector/">Features of OpenShift Connector</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../installing-openshift-connector-in-che/">Installing OpenShift Connector in Eclipse Che</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../authenticating-with-openshift-connector-from-che/">Authenticating with OpenShift Connector from Eclipse Che</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../creating-components-with-openshift-connector-in-che/">Creating Components with OpenShift Connector in Eclipse Che</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../connecting-source-code-from-github-to-a-openshift-component-using-openshift-connector/">Connecting source code from GitHub to a OpenShift Component</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../telemetry/">Telemetry</a>
<ul class="nav-list">
<li class="nav-item is-current-page" data-depth="2">
<a class="nav-link" href="./">Creating A Telemetry Plugin</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../the-woopra-telemetry-plugin/">The Woopra Telemetry Plugin</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../java-lombok/">Java Lombok</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../glossary/che-glossary/">Che glossary</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">Documentation</span>
<span class="version">master</span>
</div>
<ul class="components">
<li class="component is-current">
<a class="title" href="../../overview/introduction-to-eclipse-che/">Documentation</a>
<ul class="versions">
<li class="version is-current is-latest">
<a href="../../overview/introduction-to-eclipse-che/">master</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main class="article">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<a href="../../overview/introduction-to-eclipse-che/" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../../overview/introduction-to-eclipse-che/">Documentation</a></li>
<li>Extensions</li>
<li><a href="../telemetry/">Telemetry</a></li>
<li><a href="./">Creating A Telemetry Plugin</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/eclipse/che-docs/edit/master/modules/extensions/pages/creating-a-telemetry-plugin.adoc">Edit this Page</a></div>
</div>
<div class="content">
<aside class="toc sidebar" data-title="Contents" data-levels="2">
<div class="toc-menu"></div>
</aside>
<article class="doc">
<h1 class="page">Creating A Telemetry Plug-in</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This section shows how to create an <code>AnalyticsManager</code> class that extends <a href="https://github.com/che-incubator/che-workspace-telemetry-client/blob/master/backend-base/src/main/java/org/eclipse/che/incubator/workspace/telemetry/base/AbstractAnalyticsManager.java"><code>AbstractAnalyticsManager</code></a> and implements the following methods:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>isEnabled()</code> - determines whether or not the telemetry back-end is functioning correctly. This could mean always returning <code>true</code>, or have more complex checks, for example, returning <code>false</code> when a connection property is missing.</p>
</li>
<li>
<p><code>destroy()</code> - cleanup method that is run before shutting down the telemetry back-end. This method sends the <code>WORKSPACE_STOPPED</code> event.</p>
</li>
<li>
<p><code>onActivity()</code> - notifies that some activity is still happening for a given user. This is mainly used to send <code>WORKSPACE_INACTIVE</code> events.</p>
</li>
<li>
<p><code>onEvent()</code> - submits telemetry events to the telemetry server, such as <code>WORKSPACE_USED</code> or <code>WORKSPACE_STARTED</code>.</p>
</li>
<li>
<p><code>increaseDuration()</code> - increases the duration of a current event rather than sending multiple events in a small frame of time.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following sections cover:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Creation of a telemetry server to echo events to standard output.</p>
</li>
<li>
<p>Extending the Che telemetry client and implementing a user&#8217;s custom back-end.</p>
</li>
<li>
<p>Creating a <code>meta.yaml</code> file representing a Che workspace plug-in for a user&#8217;s custom back-end.</p>
</li>
<li>
<p>Specifying of a location of a custom plug-in to Che by setting the <code>CHE_WORKSPACE_DEVFILE_DEFAULT__EDITOR_PLUGINS</code> environment variable.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_getting_started"><a class="anchor" href="#_getting_started"></a>Getting Started</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This document describes the steps required to extend the Che telemetry system to connect to a custom back-end:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Creating a server process that receives events</p>
</li>
<li>
<p>Extending Che libraries to create a back-end that send events to the server</p>
</li>
<li>
<p>Packaging the telemetry back-end in a container and deploying it to an image registry</p>
</li>
<li>
<p>Adding a plug-in for your back-end and instructing Che to load the plug-in in your workspaces</p>
</li>
</ol>
</div>
<h2 id="_optional_creating_a_server_that_receives_events" class="discrete">Optional: creating a server that receives events</h2>
<div class="paragraph">
<p>This example shows how to create a server that receives events from Che and writes them to standard output.</p>
</div>
<div class="paragraph">
<p>For production use cases, consider integrating with a third-party telemetry system (for example, Segment, Woopra) rather than creating your own telemetry server. In this case, use your provider&#8217;s APIs to send events from your custom back-end to their system.</p>
</div>
<div class="paragraph">
<p>The following Go code starts a server on port 8080 and writes events to standard output:</p>
</div>
<div class="exampleblock">
<div class="title">Example 1. <code>main.go</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-go hljs" data-lang="go">package main
import (
"io/ioutil"
"net/http"
"go.uber.org/zap"
)
var logger *zap.SugaredLogger
func event(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case "GET":
logger.Info("GET /event")
case "POST":
logger.Info("POST /event")
}
body, err := req.GetBody()
if err != nil {
logger.With("err", err).Info("error getting body")
return
}
responseBody, err := ioutil.ReadAll(body)
if err != nil {
logger.With("error", err).Info("error reading response body")
return
}
logger.With("body", string(responseBody)).Info("got event")
}
func activity(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case "GET":
logger.Info("GET /activity, doing nothing")
case "POST":
logger.Info("POST /activity")
body, err := req.GetBody()
if err != nil {
logger.With("error", err).Info("error getting body")
return
}
responseBody, err := ioutil.ReadAll(body)
if err != nil {
logger.With("error", err).Info("error reading response body")
return
}
logger.With("body", string(responseBody)).Info("got activity")
}
}
func main() {
log, _ := zap.NewProduction()
logger = log.Sugar()
http.HandleFunc("/event", event)
http.HandleFunc("/activity", activity)
logger.Info("Added Handlers")
logger.Info("Starting to serve")
http.ListenAndServe(":8080", nil)
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Create a container image based on this code and expose it as a deployment in OpenShift in the eclipse-che namespace. The code for the example telemetry server is available at <a href="https://github.com/che-incubator/che-workspace-telemetry-example">che-workspace-telemetry-example</a>. To deploy the telemetry server, clone the repository and build the container:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ git clone https://github.com/che-incubator/che-workspace-telemetry-example
$ cd che-workspace-telemetry-example
$ docker build -t registry/organization/che-workspace-telemetry-example:latest
$ docker push registry/organization/che-workspace-telemetry-example:latest</pre>
</div>
</div>
<div class="paragraph">
<p>In <code>manifest.yaml</code>, replace the <code>image</code> and <code>host</code> fields to match the image you pushed, and the public hostname of your Kubernetes or OpenShift cluster. Then run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ kubectl apply -f manifest.yaml -n {prod-namespace}</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_creating_a_new_maven_project"><a class="anchor" href="#_creating_a_new_maven_project"></a>Creating a new Maven project</h2>
<div class="sectionbody">
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
For fast feedback when developing, it is recommended to do development inside a Che workspace. This way, you can run the application in a cluster and connect to the workspaces front-end telemetry plug-in to send events to your custom back-end.
</td>
</tr>
</table>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Create a new Maven Quarkus project scaffolding:</p>
<div class="listingblock">
<div class="content">
<pre>$ mvn io.quarkus:quarkus-maven-plugin:1.2.1.Final:create \
-DprojectGroupId=mygroup -DprojectArtifactId=telemetryback-end \
-DprojectVersion=my-version -DclassName="org.my.group.MyResource"</pre>
</div>
</div>
</li>
<li>
<p>Add a dependency to <code>org.eclipse.che.incubator.workspace-telemetry.back-end-base</code> in your <code>pom.xml</code>:</p>
<div class="exampleblock">
<div class="title">Example 2. <code>pom.xml</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.che.incubator.workspace-telemetry&lt;/groupId&gt;
&lt;artifactId&gt;backend-base&lt;/artifactId&gt;
&lt;version&gt;0.0.11&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
&lt;artifactId&gt;httpclient&lt;/artifactId&gt;
&lt;version&gt;4.5.12&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
</li>
<li>
<p>Add the Apache HTTP components library to send HTTP requests.</p>
</li>
<li>
<p>Consult the <a href="https://github.com/che-incubator/che-workspace-telemetry-client/packages">GitHub packages</a> for the latest version and Maven coordinates of <code>back-end-base</code>. <a href="https://help.github.com/en/packages/publishing-and-managing-packages/about-github-packages">GitHub packages</a> require a personal access token with <code>read:packages</code> permissions to download the Che telemetry libraries. Create a personal access token and copy the token value.</p>
</li>
<li>
<p>Create a <code>settings.xml</code> file in the repository root and add the coordinates and token to the <code>che-incubator</code> packages:</p>
<div class="exampleblock">
<div class="title">Example 3. <code>settings.xml</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml">&lt;settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd"&gt;
&lt;servers&gt;
&lt;server&gt;
&lt;id&gt;che-incubator&lt;/id&gt;
&lt;username&gt;${env.GITHUB_USERNAME}&lt;/username&gt;
&lt;password&gt;${env.GITHUB_TOKEN}&lt;/password&gt;
&lt;/server&gt;
&lt;/servers&gt;
&lt;profiles&gt;
&lt;profile&gt;
&lt;id&gt;github&lt;/id&gt;
&lt;activation&gt;
&lt;activeByDefault&gt;true&lt;/activeByDefault&gt;
&lt;/activation&gt;
&lt;repositories&gt;
&lt;repository&gt;
&lt;id&gt;central&lt;/id&gt;
&lt;url&gt;https://repo1.maven.org/maven2&lt;/url&gt;
&lt;releases&gt;&lt;enabled&gt;true&lt;/enabled&gt;&lt;/releases&gt;
&lt;snapshots&gt;&lt;enabled&gt;false&lt;/enabled&gt;&lt;/snapshots&gt;
&lt;/repository&gt;
&lt;repository&gt;
&lt;id&gt;che-incubator&lt;/id&gt;
&lt;name&gt;GitHub navikt Apache Maven Packages&lt;/name&gt;
&lt;url&gt;https://maven.pkg.github.com/che-incubator/che-workspace-telemetry-client&lt;/url&gt;
&lt;/repository&gt;
&lt;/repositories&gt;
&lt;/profile&gt;
&lt;/profiles&gt;
&lt;/settings&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>This file is used when packaging the application in a container. When running locally, add the information to your personal <code>settings.xml</code> file.</p>
</div>
</li>
</ol>
</div>
</div>
</div>
<div class="sect1">
<h2 id="running-the-application_che"><a class="anchor" href="#running-the-application_che"></a>Running the application</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Run and test the application is in a Che workspace:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn quarkus:dev -Dquarkus.http.port=${CHE_WORKSPACE_TELEMETRY_BACKEND_PORT}</pre>
</div>
</div>
<div class="paragraph">
<p>If Che is secured using a self-signed certificate, add the certificate to a trust store and mount it into the workspace. Also add the Java system property, <code>-Djavax.net.ssl.trustStore=/path/to/trustStore</code>, to the <code>mvn</code> command. For example, assuming the trust store is located in <code>$JAVA_HOME/jre/lib/security/cacerts</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ keytool -import -alias self-signed-certificate \
-file <em>&lt;path/to/self-signed-certificate&gt;</em> -keystore $JAVA_HOME/jre/lib/security/cacerts</pre>
</div>
</div>
<div class="paragraph">
<p>Followed by:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ mvn quarkus:dev -Dquarkus.http.port=${CHE_WORKSPACE_TELEMETRY_BACKEND_PORT} \
-Djavax.net.ssl.trustStore=$JAVA_HOME/jre/lib/security/cacerts</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_creating_a_concrete_implementation_of_analyticsmanager_and_adding_specialized_logic"><a class="anchor" href="#_creating_a_concrete_implementation_of_analyticsmanager_and_adding_specialized_logic"></a>Creating a concrete implementation of AnalyticsManager and adding specialized logic</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Create two new files in your project:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>AnalyticsManager.java</code> - contains the logic specific to the telemetry system.</p>
</li>
<li>
<p><code>MainConfiguration.java</code> - is the main entrypoint that creates an instance of <code>AnalyticsManager</code> and starts listening for events.</p>
</li>
</ul>
</div>
<div class="exampleblock">
<div class="title">Example 4. <code>AnalyticsManager.java</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">package org.my.group;
import java.util.Map;
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
import org.eclipse.che.incubator.workspace.telemetry.base.AbstractAnalyticsManager;
import org.eclipse.che.incubator.workspace.telemetry.base.AnalyticsEvent;
public class AnalyticsManager extends AbstractAnalyticsManager {
public AnalyticsManager(String apiEndpoint, String workspaceId, String machineToken,
HttpJsonRequestFactory requestFactory) {
super(apiEndpoint, workspaceId, machineToken, requestFactory);
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void onEvent(AnalyticsEvent event, String ownerId, String ip, String userAgent, String resolution,
Map&lt;String, Object&gt; properties) {
// TODO Auto-generated method stub
}
@Override
public void increaseDuration(AnalyticsEvent event, Map&lt;String, Object&gt; properties) {
// TODO Auto-generated method stub
}
@Override
public void onActivity() {
// TODO Auto-generated method stub
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">Example 5. <code>MainConfiguration.java</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">package org.my.group;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
import org.eclipse.che.incubator.workspace.telemetry.base.AbstractAnalyticsManager;
import org.eclipse.che.incubator.workspace.telemetry.base.BaseConfiguration;
@Dependent
public class MainConfiguration extends BaseConfiguration {
@Produces
public AbstractAnalyticsManager analyticsManager() {
return new AnalyticsManager(apiEndpoint, workspaceId, machineToken, requestFactory());
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementing_isenabled"><a class="anchor" href="#_implementing_isenabled"></a>Implementing <code>isEnabled()</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p>For the purposes of the example, this method just returns <code>true</code> whenever it is called. Whenever the server is running, it is enabled and operational.</p>
</div>
<div class="exampleblock">
<div class="title">Example 6. <code>AnalyticsManager.java</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Override
public boolean isEnabled() {
return true;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>It is possible to put more a complex login in <code>isEnabled()</code>. For example, the service should not be considered operational in certain cases. The <a href="https://github.com/redhat-developer/che-workspace-telemetry-woopra-backend/blob/master/src/main/java/com/redhat/che/workspace/services/telemetry/woopra/AnalyticsManager.java">hosted Che woopra back-end</a> checks that a configuration property exists before determining if the back-end is enabled.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementing_onevent"><a class="anchor" href="#_implementing_onevent"></a>Implementing <code>onEvent()</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p><code>onEvent()</code> sends the event passed to the back-end to the telemetry system. For the example application, it sends an HTTP POST payload to the telemetry server. The example telemetry server application is deployed to OpenShift at the following URL: <code>http://little-telemetry-back-end-che.apps-crc.testing</code>.</p>
</div>
<div class="exampleblock">
<div class="title">Example 7. <code>AnalyticsManager.java</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Override
public void onEvent(AnalyticsEvent event, String ownerId, String ip, String userAgent, String resolution, Map&lt;String, Object&gt; properties) {
HttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://little-telemetry-backend-che.apps-crc.testing/event");
HashMap&lt;String, Object&gt; eventPayload = new HashMap&lt;String, Object&gt;(properties);
eventPayload.put("event", event);
StringEntity requestEntity = new StringEntity(new JsonObject(eventPayload).toString(),
ContentType.APPLICATION_JSON);
httpPost.setEntity(requestEntity);
try {
HttpResponse response = httpClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>This sends an HTTP request to the telemetry server and automatically delays identical events in a small time period, where the default value is 1500 milliseconds. It is possible to modify this period by setting subclasses.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementing_increaseduration"><a class="anchor" href="#_implementing_increaseduration"></a>Implementing <code>increaseDuration()</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Many telemetry systems recognize event duration. The <code>AbstractAnalyticsManager</code> merges similar events that happen in the same frame of time into one event, so that a user does not get several identical events sent to the server in a small time frame. This implementation of <code>increaseDuration()</code> is a no-op. This method uses the APIs of a user&#8217;s telemetry provider to alter the event or event properties to reflect an event&#8217;s increased duration.</p>
</div>
<div class="exampleblock">
<div class="title">Example 8. <code>AnalyticsManager.java</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Override
public void increaseDuration(AnalyticsEvent event, Map&lt;String, Object&gt; properties) {}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementing_onactivity"><a class="anchor" href="#_implementing_onactivity"></a>Implementing <code>onActivity()</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Set an inactive timeout limit, and use <code>onActivity()</code> to send a <code>WORKSPACE_INACTIVE</code> event if the last event time is longer than the inactivity timeout.</p>
</div>
<div class="exampleblock">
<div class="title">Example 9. <code>AnalyticsManager.java</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class AnalyticsManager extends AbstractAnalyticsManager {
...
private long inactiveTimeLimt = 60000 * 3;
...
@Override
public void onActivity() {
if (System.currentTimeMillis() - lastEventTime &gt;= inactiveTimeLimt) {
onEvent(WORKSPACE_INACTIVE, lastOwnerId, lastIp, lastUserAgent, lastResolution, commonProperties);
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementing_destroy"><a class="anchor" href="#_implementing_destroy"></a>Implementing <code>destroy()</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p>When <code>destroy()</code> is called, send a <code>WORKSPACE_STOPPED</code> event and shutdown any resources, such as connection pools.</p>
</div>
<div class="exampleblock">
<div class="title">Example 10. <code>AnalyticsManager.java</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Override
public void destroy() {
onEvent(WORKSPACE_STOPPED, lastOwnerId, lastIp, lastUserAgent, lastResolution, commonProperties);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Running <code>mvn quarkus:dev</code> as described in <a href="#running-the-application_che">Running the application</a> displays the <code>WORKSPACE_STOPPED</code> event, sent to the server when the Quarkus application is terminated.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_packaging_the_quarkus_application"><a class="anchor" href="#_packaging_the_quarkus_application"></a>Packaging the Quarkus application</h2>
<div class="sectionbody">
<div class="paragraph">
<p>See <a href="https://quarkus.io/guides/building-native-image#using-a-multi-stage-docker-build">the quarkus documentation</a> for the best instructions to package the application in a container. Build and push the container to a container registry of your choice.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_creating_a_meta_yaml_for_your_plug_in"><a class="anchor" href="#_creating_a_meta_yaml_for_your_plug_in"></a>Creating a <code>meta.yaml</code> for your plug-in.</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Create a <code>meta.yaml</code> definition representing a Che plug-in that runs your custom back-end in a workspace Pod. For more information about <code>meta.yaml</code>, see <a href="../../end-user-guide/what-is-a-che-theia-plug-in/" class="page">What is a Che-Theia plug-in</a>.</p>
</div>
<div class="exampleblock">
<div class="title">Example 11. meta.yaml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">apiVersion: v2
publisher: demo-publisher
name: little-telemetry-backend
version: 0.0.1
type: Che Plugin
displayName: Little Telemetry Backend
description: A Demo telemetry backend
title: Little Telemetry Backend
category: Other
spec:
workspaceEnv:
- name: CHE_WORKSPACE_TELEMETRY_BACKEND_PORT
value: '4167'
containers:
- name: YOUR BACKEND NAME
image: YOUR IMAGE NAME
env:
- name: CHE_API
value: $(CHE_API_INTERNAL)</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In most cases, a user would deploy this file to a corporate web server. This guide demonstrates how to create an Apache web server on OpenShift and host the plug-in there.</p>
</div>
<div class="paragraph">
<p>Create a ConfigMap referencing the new <code>meta.yaml</code> file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ oc create configmap --from-file=meta.yaml -n eclipse-che telemetry-plugin-meta</pre>
</div>
</div>
<div class="paragraph">
<p>Create a deployment, a service, and a route to expose the web server. The deployment references this ConfigMap and places it in the <code>/var/www/html</code> directory.</p>
</div>
<div class="exampleblock">
<div class="title">Example 12. <code>manifests.yaml</code></div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">kind: Deployment
apiVersion: apps/v1
metadata:
name: apache
namespace: <em>&lt;eclipse-che&gt;</em>
spec:
replicas: 1
selector:
matchLabels:
app: apache
template:
metadata:
labels:
app: apache
spec:
volumes:
- name: plugin-meta-yaml
configMap:
name: telemetry-plugin-meta
defaultMode: 420
containers:
- name: apache
image: 'registry.redhat.io/rhscl/httpd-24-rhel7:latest'
ports:
- containerPort: 8080
protocol: TCP
resources: {}
volumeMounts:
- name: plugin-meta-yaml
mountPath: /var/www/html
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
---
kind: Service
apiVersion: v1
metadata:
name: apache
namespace: <em>&lt;eclipse-che&gt;</em>
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: apache
type: ClusterIP
---
kind: Route
apiVersion: route.openshift.io/v1
metadata:
name: apache
namespace: <em>&lt;eclipse-che&gt;</em>
spec:
host: apache-che.apps-crc.testing
to:
kind: Service
name: apache
weight: 100
port:
targetPort: 8080
wildcardPolicy: None</code></pre>
</div>
</div>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>$ oc apply -f manifests.yaml</pre>
</div>
</div>
<div class="paragraph">
<p>Wait a few minutes for the image to pull and the deployment to start, and then confirm that <code>meta.yaml</code> is available in the web server:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>$ curl apache-che.apps-crc.testing/meta.yaml</pre>
</div>
</div>
<div class="paragraph">
<p>This command should return the <code>meta.yaml</code> file.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_updating_che_to_reference_your_telemetry_plug_in"><a class="anchor" href="#_updating_che_to_reference_your_telemetry_plug_in"></a>Updating Che to reference your telemetry plug-in</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Update the <code>CheCluster</code> Custom Resource, and add the <code>CHE_WORKSPACE_DEVFILE_DEFAULT__EDITOR_PLUGINS</code> environment variable to <code>spec.server.customCheProperties</code>. The value of the environment variable must be the URL of the location of the <code>meta.yaml</code> file on your web server. This can be accomplished by running <code>oc edit checluster -n eclipse-che</code> and typing in the change at the terminal, or by editing the CR in the OpenShift console (<strong>Installed Operators &#8594; Eclipse&#160;Che &#8594; Eclipse&#160;Che Cluster &#8594; eclipse-che &#8594; YAML</strong>).</p>
</div>
<div class="exampleblock">
<div class="title">Example 13. Example of a YAML file</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">apiVersion: org.eclipse.che/v1
kind: CheCluster
metadata:
creationTimestamp: '2020-05-14T13:21:51Z'
finalizers:
- oauthclients.finalizers.che.eclipse.org
generation: 18
name: eclipse-che
namespace: <em>&lt;eclipse-che&gt;</em>
resourceVersion: '5108404'
selfLink: /apis/org.eclipse.che/v1/namespaces/che/checlusters/eclipse-che
uid: bae08db2-104d-4e44-a001-c9affc07528d
spec:
auth:
identityProviderURL: 'https://keycloak-che.apps-crc.testing'
identityProviderRealm: che
updateAdminPassword: false
oAuthSecret: ZMmNPRbgOJJQ
oAuthClientName: eclipse-che-openshift-identity-provider-yrlcxs
identityProviderClientId: che-public
identityProviderPostgresSecret: che-identity-postgres-secret
externalIdentityProvider: false
identityProviderSecret: che-identity-secret
openShiftoAuth: true
database:
chePostgresDb: dbche
chePostgresHostName: postgres
chePostgresPort: '5432'
chePostgresSecret: che-postgres-secret
externalDb: false
k8s: {}
metrics:
enable: false
server:
cheLogLevel: INFO
customCheProperties:
CHE_WORKSPACE_DEVFILE_DEFAULT__EDITOR_PLUGINS: 'http://apache-che.apps-crc.testing/meta.yaml'
externalDevfileRegistry: false
cheHost: che-che.apps-crc.testing
selfSignedCert: true
cheDebug: 'false'
tlsSupport: true
allowUserDefinedWorkspaceNamespaces: false
externalPluginRegistry: false
gitSelfSignedCert: false
cheFlavor: che
storage:
preCreateSubPaths: true
pvcClaimSize: 1Gi
pvcStrategy: per-workspace
status:
devfileRegistryURL: 'https://devfile-registry-che.apps-crc.testing'
keycloakProvisioned: true
cheClusterRunning: Available
cheURL: 'https://che-che.apps-crc.testing'
openShiftoAuthProvisioned: true
dbProvisioned: true
cheVersion: 7.13.1
keycloakURL: 'https://keycloak-che.apps-crc.testing'
pluginRegistryURL: 'https://plugin-registry-che.apps-crc.testing/v3'</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Wait for the Che server to restart, and create a new workspace. See a new message stating that the plug-in is being installed into the workspace.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="../_images/telemetry/custom_telemetry_plugin.png" alt="custom telemetry plugin">
</div>
</div>
<div class="paragraph">
<p>Perform any operations in the started workspace and observe their events in the example telemetry server logs.</p>
</div>
</div>
</div>
</article>
</div>
</main>
</div>
<footer class="footer">
<div><a href="https://www.eclipse.org" target="_blank">Eclipse Foundation</a> |
<a href="https://www.eclipse.org/legal/privacy.php" target="_blank">Privacy Policy</a> |
<a href="https://www.eclipse.org/legal/termsofuse.php" target="_blank">Terms of Use</a> |
<a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank">Eclipse Public License</a> |
<a href="https://www.eclipse.org/legal" target="_blank">Legal Resources</a></div>
</footer>
<script src="../../../_/js/site.js"></script>
<script async src="../../../_/js/vendor/highlight.js"></script>
</body>
</html>