Package: jupyterlab-telemetry-producer-demo
JupyterLab Telemetry Producer DemoA JupyterLab extension that generates telemetry data when users click on a button.This extension relies on thejupyterlab-telemetry-routerextension.JupyterLab Telemetry Producer DemoGetting startedRequirementsInstallUninstallHow to implement a custom telemetry producer extensionImplement the extension from scratchImplement the extension based on the demo extensionDevelopment WorkflowClient SideServer SideUseful linksDevelopment uninstallPackaging the extensionHow to utilize the telemetry router extension to export telemetry dataOverviewRouter ConfigurationSyntaxConfiguration file name & pathExample(Optional) Event Producer(Optional) Producer ConfigurationConfiguration file name & pathRecommended SyntaxTroubleshootGetting startedRequirementsJupyterLab >= 4.0.0InstallTo install the extension, execute:pipinstalljupyterlab-telemetry-producer-demoThe telemetry router extension is automatically installed when the telemetry producer is installed.Users need to write their own router configuration file (or use the configuration example) and place it in the correct directory before starting Jupyter Lab with the telemetry system.Examples of router configurations arehere.Examples of producer configurations arehereUninstallTo remove the extension, execute:pipuninstalljupyterlab-telemetry-producer-demoHow to implement a custom telemetry producer extensionSet up development environmentconda create -n telemetry-demo --override-channels --strict-channel-priority -c conda-forge -c nodefaults jupyterlab=4 nodejs=18 copier=8 jinja2-time jupyter-packaging git

conda activate telemetry-demoImplement the extension from scratchInitialize from the extension templatemkdir jupyterlab-telemetry-producer-demo

cd jupyterlab-telemetry-producer-demo

copier copy --UNSAFE https://github.com/jupyterlab/extension-template .Addjupyterlab-telemetry-routeras a dependency inpyproject.toml.dependencies=["jupyter_server>=2.0.1,<3","jupyterlab-telemetry-router"]Note: You will need NodeJS to build the extension package.Thejlpmcommand is JupyterLab's pinned version ofyarnthat is installed with JupyterLab. You may useyarnornpmin lieu ofjlpmbelow.# Install package in development modepipinstall-e"."# Link your development version of the extension with JupyterLabjupyterlabextensiondevelop.--overwrite# Server extension must be manually installed in develop modejupyterserverextensionenablejupyterlab-telemetry-producer-demo# Rebuild extension Typescript source after making changesjlpmbuildYou can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.# Watch the source directory in one terminal, automatically rebuilding when neededjlpmwatch# Run JupyterLab in another terminaljupyterlabImplement the extension based on the demo extension# Clone the repo to your local environmentgitclonehttps://github.com/educational-technology-collective/jupyterlab-telemetry-producer-demo# Change directory to the jupyterlab-telemetry-producer-demo directorycdjupyterlab-telemetry-producer-demo# Install package in development modepipinstall-e"."# Link your development version of the extension with JupyterLabjupyterlabextensiondevelop.--overwrite# Server extension must be manually installed in develop modejupyterserverextensionenablejupyterlab-telemetry-producer-demo# Rebuild extension Typescript source after making changesjlpmbuild# Or watch the source directory in one terminal, automatically rebuilding when neededjlpmwatch# Run JupyterLab in another terminaljupyterlabWith the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).By default, thejlpm buildcommand generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:jupyterlabbuild--minimize=FalseDevelopment WorkflowClient SideMake changes to the TypeScript client extension.Refresh the browser.Observe the changes in the running application.Server SideMake changes to the Python server extension.Stop the Jupyter server.Start the Jupyter server.Observe the changes in the running application.Useful linkshttps://jupyterlab.readthedocs.io/en/stable/extension/extension_tutorial.htmlhttps://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.htmlhttps://github.com/educational-technology-collective/jupyterlab-telemetry-routerhttps://github.com/educational-technology-collective/jupyterlab-telemetry-producerDevelopment uninstall# Server extension must be manually disabled in develop modejupyterserverextensiondisablejupyterlab-telemetry-producer-demo
pipuninstalljupyterlab-telemetry-producer-demoIn development mode, you will also need to remove the symlink created byjupyter labextension developcommand. To find its location, you can runjupyter labextension listto figure out where thelabextensionsfolder is located. Then you can remove the symlink namedjupyterlab-telemetry-producer-demowithin that folder.Packaging the extensionSeeRELEASEHow to utilize the telemetry router extension to export telemetry dataOverviewThe telemetry-router extension helps to monitor notebook states and export telemetry data to the console, local file, or any remote endpoints.The telemetry router extension provides two methods to the producer extension,loadNotebookPanelandpublishEvent.loadNotebookPanelshould be called first when activating the producer extension, to associate the telemetry events with the correct notebook panel before exporting data.publishEventcould be called whenever we want to publish the event and export telemetry data to the desired endpoints. ThepublishEventmethod takes two arguments,eventDetail: ObjectandlogNotebookContent: Boolean.There is generally no limitation on the structure of theeventDetailobject, as long as the information is wrapped in a serializable javascript object.logNotebookContentis optional and should be aBooleanobject. Only if it is provided and istrue, the router will send out the entire notebook content along with the event data.WhenpublishEventis called, the router checks if the notebook panel is loaded properly, and then insert the notebook session ID, notebook file path, and the notebook content (whenlogNotebookContentistrue) into the data. Then, the router checks the type of each exporter, processes and sends out the data one by one. Ifenvandparamsare provided in the configuration file when defining the desired exporter, the router would extract the environment variables and add the params to the exported data. Finally, the router will assemble the responses from the exporters in an array and print the response array in the console.Router ConfigurationThe telemetry router extension is driven by the configuration file. In this way, users can define exporters easily without touching the extension code.Thejupyterlab-telemetry-routerextension provides 3 types of default exporters,consoleexporter,fileexporter andremoteexporter.consoleexporter logs data in the console.fileexporter logs data into the local file indicated bypath.remoteexporter posts data to the remote endpoint indicated byurl.The extension would extract the environment variable for each of the keys presented inenv, and add the result to the data when exporting.The extension would addparamsdirectly to data when exporting. This feature is useful when users want to post data to lambda functions and wants to have additional parameters.Syntaxtypeandidare required for all exporters.pathis required for file exporters only.urlis required for remote exporters only.envandparamsare optional.When the extension is being activated, a syntax check will be done first. Missing required fields would prevent Jupyter Lab from starting.Configuration file name & pathJupyter Server expects the configuration file to be named after the extension’s name like so:jupyter_{extension name defined in application.py}_config.py. In our case, the extension name is definedhere. So, the configuration file name isjupyter_jupyterlab_telemetry_router_config.py.Jupyter Server looks for an extension’s config file in a set of specific paths.The configuration file should be saved into one of the config directories provided byjupyter --path.For more details, seehttps://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.html.Example## in jupyter_jupyterlab_telemetry_router_config.pyc.JupyterLabTelemetryRouterApp.exporters=[{'type':'console','id':'ConsoleExporter',},{'type':'file','id':'FileExporter','path':'log',},{'type':'remote','id':'S3Exporter','url':'https://telemetry.mentoracademy.org/telemetry-edtech-labs-si-umich-edu/dev/test-telemetry','env':['WORKSPACE_ID']}](Optional) Event ProducerThere is no specific restrictions on when and where the telemetry router should be invoked. However, when writing complex event producer libraries, we recommend developers write an event producer class for each event, implement alisten()class method, and call the producer'slisten()method when the producer extension is being activated. Within thelisten()method, you may write the logic of how the extension listens to Jupyter signals or DOM events and how to use thetelemetryRouter.publishEvent()function to export telemetry data.For detailed examples, seehttps://github.com/educational-technology-collective/telemetry-producer/blob/main/src/events.tsandhttps://github.com/educational-technology-collective/telemetry-producer/blob/main/src/index.ts#L31.(Optional) Producer ConfigurationUnlike the telemetry router extension, using a configuration file is not required when implementing telemetry producer extensions.In this telemetry producer demo extension, there is only one event and actually does not need to go through the configuration.However, writing code on top of the configuration file might be very useful when the event library is complex, and when the telemetry system is going to be deployed under different contexts with different needs of telemetry events.Configuration file name & pathJupyter Server expects the configuration file to be named after the extension’s name like so: jupyter_{extension name defined inapplication.py}_config.py. In our case, the configuration file name isjupyter_jupyterlab_telemetry_producer_demo_config.py.Jupyter Server looks for an extension’s config file in a set of specific paths. Usejupyter --pathscommand to list these paths and place the configuration file in any of the paths.For more details, seehttps://jupyter-server.readthedocs.io/en/latest/operators/configuring-extensions.html.Recommended SyntaxWe recommend developers to use the following configuration syntax when writing their own telemetry producers.activateEvents: required. An array of the ids of the events. Only valid event producers (1. has an id associated with the event producer class, and 2. the event id is included inactivatedEvents) will be activated.logNotebookContentEvents: optional. An array of the ids of the events. Only valid event producers (1. has an id associated with the event producer class, and 2. the event id is included inlogNotebookContentEvents) will have the router export the entire notebook content along with the event data.## in jupyter_jupyterlab_telemetry_producer_demo_config.pyc.JupyterLabTelemetryProducerDemoApp.activeEvents=['ClickButtonEvent',]c.JupyterLabTelemetryProducerDemoApp.logNotebookContentEvents=['ClickButtonEvent',]TroubleshootIf you are seeing the frontend extension, but it is not working, check
that the server extension is enabled:jupyterserverextensionlistIf the server extension is installed and enabled, but you are not seeing
the frontend extension, check the frontend extension is installed:jupyterlabextensionlist