This section shows how to create an AnalyticsManager
class that extends AbstractAnalyticsManager
and implements the following methods:
-
isEnabled()
- determines whether the telemetry back-end is functioning correctly. This can mean always returningtrue
, or have more complex checks, for example, returningfalse
when a connection property is missing. -
destroy()
- cleanup method that is run before shutting down the telemetry back-end. This method sends theWORKSPACE_STOPPED
event. -
onActivity()
- notifies that some activity is still happening for a given user. This is mainly used to sendWORKSPACE_INACTIVE
events. -
onEvent()
- submits telemetry events to the telemetry server, such asWORKSPACE_USED
orWORKSPACE_STARTED
. -
increaseDuration()
- increases the duration of a current event rather than sending many events in a small frame of time.
The following sections cover:
-
Creating a telemetry server to echo events to standard output.
-
Extending the {prod-short} telemetry client and implementing a user’s custom back-end.
-
Creating a
plugin.yaml
file representing a {devworkspace} plug-in for the custom back-end. -
Specifying of a location of a custom plug-in to {prod-short} by setting the
workspacesDefaultPlugins
attribute from theCheCluster
custom resource.
This document describes the steps required to extend the {prod-short} telemetry system to communicate with to a custom back-end:
-
Creating a server process that receives events
-
Extending {prod-short} libraries to create a back-end that send events to the server
-
Packaging the telemetry back-end in a container and deploying it to an image registry
-
Adding a plug-in for your back-end and instructing {prod-short} to load the plug-in in your {devworkspace}s
A finished example of the telemetry back-end is available here.
For demonstration purposes, this example shows how to create a server that receives events from our telemetry plug-in and writes them to standard output.
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’s APIs to send events from your custom back-end to their system.
The following Go code starts a server on port 8080
and writes events to standard output:
main.go
link:example$creating-a-telemetry-plug-in-for-devworkspaces/main.go[role=include]
Create a container image based on this code and expose it as a deployment in OpenShift in the {prod-namespace} {orch-namespace}. The code for the example telemetry server is available at telemetry-server-example. To deploy the telemetry server, clone the repository and build the container:
$ git clone https://github.com/che-incubator/telemetry-server-example $ cd telemetry-server-example $ docker build -t registry/organization/telemetry-server-example:latest . $ docker push registry/organization/telemetry-server-example:latest
Both manifest_with_ingress.yaml
and manifest_with_route
contain definitions for a Deployment and Service. The former also defines a {kubernetes} Ingress, while the latter defines also an OpenShift Route.
In the manifest file, replace the image
and host
fields to match the image you pushed, and the public hostname of your {platforms-name} cluster. Then run:
$ kubectl apply -f manifest_with_[ingress|route].yaml -n {prod-namespace}
Note
|
For fast feedback when developing, it is recommended to do development inside a {devworkspace}. This way, you can run the application in a cluster and receive events from the front-end telemetry plug-in. |
-
Maven Quarkus project scaffolding:
$ mvn io.quarkus:quarkus-maven-plugin:2.7.1.Final:create \ -DprojectGroupId=mygroup -DprojectArtifactId=devworkspace-telemetry-example-plugin \ -DprojectVersion=1.0.0-SNAPSHOT
-
Remove the files under
src/main/java/mygroup
andsrc/test/java/mygroup
. -
Consult the GitHub packages for the latest version and Maven coordinates of
backend-base
. -
Add the following dependencies to your
pom.xml
:Example 2.pom.xml
link:example$creating-a-telemetry-plug-in-for-devworkspaces/pom_snippet.xml[role=include]
-
Create a personal access token with
read:packages
permissions to download theorg.eclipse.che.incubator.workspace-telemetry:backend-base
dependency from GitHub packages. -
Add your GitHub username, personal access token and
che-incubator
repository details in your~/.m2/settings.xml
file:Example 3.settings.xml
link:example$creating-a-telemetry-plug-in-for-devworkspaces/settings.xml[role=include]
Create two new files in your project under src/main/java/mygroup
:
-
MainConfiguration.java
- contains configuration provided toAnalyticsManager
. -
AnalyticsManager.java
- contains logic specific to the telemetry system.
MainConfiguration.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/MainConfiguration.java[role=include]
-
A MicroProfile configuration annotation is used to inject the
welcome.message
configuration.
For more details on how to set configuration properties specific to your back-end, see the Quarkus Configuration Reference Guide.
AnalyticsManager.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/AnalyticsManagerSkeleton.java[role=include]
-
Log the welcome message if it was provided
-
Log the event received from the front-end plug-in
Since org.my.group.AnalyticsManager
and org.my.group.MainConfiguration
are alternative beans, specify them using the quarkus.arc.selected-alternatives
property in src/main/resources/application.properties
.
application.properties
quarkus.arc.selected-alternatives=MainConfiguration,AnalyticsManager
-
Set the
DEVWORKSPACE_TELEMETRY_BACKEND_PORT
environment variable in the {devworkspace}. Here, the value is set to4167
.spec: template: attributes: workspaceEnv: - name: DEVWORKSPACE_TELEMETRY_BACKEND_PORT value: '4167'
-
Restart the {devworkspace} from the {prod} dashboard.
-
From a terminal window, run the application by running the following command within a {devworkspace}. Use the
--settings
flag to specify path to the location of thesettings.xml
file that contains the GitHub access token.$ mvn --settings=settings.xml quarkus:dev -Dquarkus.http.port=${DEVWORKSPACE_TELEMETRY_BACKEND_PORT}
The application now receives telemetry events through port
4167
from the front-end plug-in.
-
Verify that the following output is be logged:
INFO [org.ecl.che.inc.AnalyticsManager] (Quarkus Main Thread) No welcome message provided INFO [io.quarkus] (Quarkus Main Thread) devworkspace-telemetry-example-plugin 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.7.2.Final) started in 0.323s. Listening on: http://localhost:4167 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, kubernetes-client, rest-client, rest-client-jackson, resteasy, resteasy-jsonb, smallrye-context-propagation, smallrye-openapi, swagger-ui, vertx]
-
To verify that the
onEvent()
method ofAnalyticsManager
receives events from the front-end plug-in, press the kbd:[l] key to disable Quarkus live coding and edit any file within the IDE. The following output should be logged:INFO [io.qua.dep.dev.RuntimeUpdatesProcessor] (Aesh InputStream Reader) Live reload disabled INFO [org.ecl.che.inc.AnalyticsManager] (executor-thread-2) The received event is: Edit Workspace File in Che
For the purposes of the example, this method just returns true
whenever it is called. Whenever the server is running, it is enabled and operational.
AnalyticsManager.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/isEnabled.java[role=include]
It is possible to put more complex logic in isEnabled()
. For example, the hosted {prod-short} woopra back-end checks that a configuration property exists before determining if the back-end is enabled.
onEvent()
sends the event received by the back-end to the telemetry system. For the example application, it sends an HTTP POST payload to the /event
endpoint from the telemetry server.
For the following example, the telemetry server application is deployed to OpenShift at the following URL: http://little-telemetry-server-che.apps-crc.testing
, where apps-crc.testing
is the ingress domain name of the OpenShift cluster.
-
Set up the RESTEasy REST Client by creating
TelemetryService.java
Example 8.TelemetryService.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/TelemetryService.java[role=include]
-
The endpoint to make the
POST
request to.
-
-
Specify the base URL for
TelemetryService
in thesrc/main/resources/application.properties
file:Example 9.application.properties
org.my.group.TelemetryService/mp-rest/url=http://little-telemetry-server-che.apps-crc.testing
-
Inject
TelemetryService
intoAnalyticsManager
and send aPOST
request inonEvent()
Example 10.AnalyticsManager.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/onEvent.java[role=include]
This sends an HTTP request to the telemetry server and automatically delays identical events for a small period of time. The default duration is 1500 milliseconds.
Many telemetry systems recognize event duration. The AbstractAnalyticsManager
merges similar events that happen in the same frame of time into one event. This implementation of increaseDuration()
is a no-op. This method uses the APIs of the user’s telemetry provider to alter the event or event properties to reflect the increased duration of an event.
AnalyticsManager.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/increaseDuration.java[role=include]
Set an inactive timeout limit, and use onActivity()
to send a WORKSPACE_INACTIVE
event if the last event time is longer than the timeout.
AnalyticsManager.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/onActivity.java[role=include]
When destroy()
is called, send a WORKSPACE_STOPPED
event and shutdown any resources, such as connection pools.
AnalyticsManager.java
link:example$creating-a-telemetry-plug-in-for-devworkspaces/destroy.java[role=include]
Running mvn quarkus:dev
as described in Running the application within a {devworkspace} and terminating the application with kbd:[Ctrl+C] sends WORKSPACE_STOPPED
event sent to the server.
See the Quarkus documentation for the best instructions to package the application in a container. Build and push the container to a container registry of your choice.
Dockerfile.jvm
link:example$creating-a-telemetry-plug-in-for-devworkspaces/Dockerfile.jvm[role=include]
To build the image, run:
mvn package && \ docker build -f src/main/docker/Dockerfile.jvm -t image:tag .
Dockerfile.native
link:example$creating-a-telemetry-plug-in-for-devworkspaces/Dockerfile.native[role=include]
To build the image, run:
mvn package -Pnative -Dquarkus.native.container-build=true && \ docker build -f src/main/docker/Dockerfile.native -t image:tag .
Create a plugin.yaml
devfile v2 file representing a {devworkspace} plug-in that runs your custom back-end in a workspace Pod. For more information about devfile v2, see Devfile v2 documentation
plugin.yaml
link:example$creating-a-telemetry-plug-in-for-devworkspaces/plugin.yaml[role=include]
-
Specify the container image built from Packaging the Quarkus application
-
Setting the value for the
welcome.message
optional configuration property from Example 4.
Typically, the user deploys 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.
Create a ConfigMap referencing the new plugin.yaml
file.
$ oc create configmap --from-file=plugin.yaml -n {prod-namespace} telemetry-plugin-yaml
Create a deployment, a service, and a route to expose the web server. The deployment references this ConfigMap and places it in the /var/www/html
directory.
manifest.yaml
link:example$creating-a-telemetry-plug-in-for-devworkspaces/webserver.yaml[role=include]
$ oc apply -f manifest.yaml
After the deployment has started to start, confirm that plugin.yaml
is available in the web server:
$ curl apache-che.apps-crc.testing/plugin.yaml
-
Add the following to the
components
field to an existing {devworkspace}:components: ... - name: telemetry-plug-in plugin: uri: http://apache-che.apps-crc.testing/plugin.yaml
-
Start the {devworkspace} from the {prod-short} dashboard.
Set the telemetry plug-in as a default plug-in in the spec.server.workspaceDefaultPlugins
field for the CheCluster
custom resource. Default plug-ins are applied on {devworkspace} startup for new and existing {devworkspace}s.
spec: ... server: ... workspacesDefaultPlugins: - editor: eclipse/che-theia/next (1) plugins: (2) - 'http://apache-che.apps-crc.testing/plugin.yaml'
-
The editorId to set default plug-ins for
-
List of URLs to devfile v2 plug-ins
This can be accomplished by running oc edit checluster -n {prod-namespace}
and typing in the change at the terminal, or by editing the CR in the OpenShift console (Installed Operators → {prod} → {prod} Cluster → {prod-checluster} → YAML).
For more information about the Che Cluster custom resource, see installation-guide:understanding-the-checluster-custom-resource.adoc.
-
Start a new or existing {devworkspace} from the {prod} dashboard.
-
Verify that the telemetry plug-in is working by following the verification steps for Specifying the telemetry plug-in in a {devworkspace}.