notebook-metrics 1.0.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- notebook_metrics-1.0.0a1/.copier-answers.yml +14 -0
- notebook_metrics-1.0.0a1/.gitignore +129 -0
- notebook_metrics-1.0.0a1/.prettierignore +6 -0
- notebook_metrics-1.0.0a1/.yarnrc.yml +1 -0
- notebook_metrics-1.0.0a1/CHANGELOG.md +5 -0
- notebook_metrics-1.0.0a1/LICENSE +26 -0
- notebook_metrics-1.0.0a1/ONBOARDING.md +274 -0
- notebook_metrics-1.0.0a1/PKG-INFO +250 -0
- notebook_metrics-1.0.0a1/README.md +190 -0
- notebook_metrics-1.0.0a1/RELEASE.md +148 -0
- notebook_metrics-1.0.0a1/babel.config.js +1 -0
- notebook_metrics-1.0.0a1/conftest.py +8 -0
- notebook_metrics-1.0.0a1/install.json +5 -0
- notebook_metrics-1.0.0a1/jest.config.js +31 -0
- notebook_metrics-1.0.0a1/jupyter-config/server-config/notebook_metrics.json +7 -0
- notebook_metrics-1.0.0a1/notebook_metrics/__init__.py +44 -0
- notebook_metrics-1.0.0a1/notebook_metrics/_version.py +4 -0
- notebook_metrics-1.0.0a1/notebook_metrics/emissions/command-executed.yml +42 -0
- notebook_metrics-1.0.0a1/notebook_metrics/emissions/current-changed.yml +31 -0
- notebook_metrics-1.0.0a1/notebook_metrics/emissions/jupyter-error.yml +45 -0
- notebook_metrics-1.0.0a1/notebook_metrics/emissions/runtime-error.yml +33 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/package.json +212 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/schemas/notebook-metrics/dispatcher.json +55 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/schemas/notebook-metrics/package.json.orig +207 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/static/547.d2fe90605306675c07f8.js +1 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/static/728.3fabb3bacc277b6a9f4b.js +1 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/static/remoteEntry.c547d360419976803e19.js +1 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/static/style.js +4 -0
- notebook_metrics-1.0.0a1/notebook_metrics/labextension/static/third-party-licenses.json +16 -0
- notebook_metrics-1.0.0a1/notebook_metrics/tests/__init__.py +1 -0
- notebook_metrics-1.0.0a1/notebook_metrics/tests/test_pass.py +50 -0
- notebook_metrics-1.0.0a1/package.json +207 -0
- notebook_metrics-1.0.0a1/pyproject.toml +89 -0
- notebook_metrics-1.0.0a1/schema/dispatcher.json +55 -0
- notebook_metrics-1.0.0a1/setup.py +1 -0
- notebook_metrics-1.0.0a1/src/__tests__/notebook_metrics.spec.ts +334 -0
- notebook_metrics-1.0.0a1/src/emissions/command-executed.ts +62 -0
- notebook_metrics-1.0.0a1/src/emissions/current-changed.ts +54 -0
- notebook_metrics-1.0.0a1/src/emissions/jupyter-error.ts +82 -0
- notebook_metrics-1.0.0a1/src/emissions/runtime-error.ts +55 -0
- notebook_metrics-1.0.0a1/src/index.ts +3 -0
- notebook_metrics-1.0.0a1/src/metrics.ts +113 -0
- notebook_metrics-1.0.0a1/src/plugins.ts +165 -0
- notebook_metrics-1.0.0a1/style/base.css +5 -0
- notebook_metrics-1.0.0a1/style/index.css +1 -0
- notebook_metrics-1.0.0a1/style/index.js +1 -0
- notebook_metrics-1.0.0a1/tsconfig.json +26 -0
- notebook_metrics-1.0.0a1/tsconfig.test.json +3 -0
- notebook_metrics-1.0.0a1/ui-tests/README.md +171 -0
- notebook_metrics-1.0.0a1/ui-tests/event_capture_extension.py +45 -0
- notebook_metrics-1.0.0a1/ui-tests/jupyter_server_test_config.py +38 -0
- notebook_metrics-1.0.0a1/ui-tests/metrics-override.yml +8 -0
- notebook_metrics-1.0.0a1/ui-tests/package.json +18 -0
- notebook_metrics-1.0.0a1/ui-tests/playwright.config.js +20 -0
- notebook_metrics-1.0.0a1/ui-tests/tests/notebook_metrics.spec.ts +124 -0
- notebook_metrics-1.0.0a1/ui-tests/yarn.lock +5967 -0
- notebook_metrics-1.0.0a1/yarn.lock +11196 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
|
|
2
|
+
_commit: v4.3.8
|
|
3
|
+
_src_path: https://github.com/jupyterlab/extension-template
|
|
4
|
+
author_email: git@darian.link
|
|
5
|
+
author_name: Afshin T. Darian
|
|
6
|
+
has_binder: false
|
|
7
|
+
has_settings: true
|
|
8
|
+
kind: server
|
|
9
|
+
labextension_name: notebook-metrics
|
|
10
|
+
project_short_description: A JupyterLab/JupyterLite extension for Jupyter UI metrics.
|
|
11
|
+
python_name: notebook_metrics
|
|
12
|
+
repository: https://github.com/notebook-link/metrics
|
|
13
|
+
test: true
|
|
14
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
*.bundle.*
|
|
2
|
+
lib/
|
|
3
|
+
node_modules/
|
|
4
|
+
*.log
|
|
5
|
+
.eslintcache
|
|
6
|
+
.stylelintcache
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.ipynb_checkpoints
|
|
9
|
+
*.tsbuildinfo
|
|
10
|
+
notebook_metrics/labextension
|
|
11
|
+
# Version file is handled by hatchling
|
|
12
|
+
notebook_metrics/_version.py
|
|
13
|
+
|
|
14
|
+
# Integration tests
|
|
15
|
+
ui-tests/test-results/
|
|
16
|
+
ui-tests/playwright-report/
|
|
17
|
+
|
|
18
|
+
# Created by https://www.gitignore.io/api/python
|
|
19
|
+
# Edit at https://www.gitignore.io/?templates=python
|
|
20
|
+
|
|
21
|
+
### Python ###
|
|
22
|
+
# Byte-compiled / optimized / DLL files
|
|
23
|
+
__pycache__/
|
|
24
|
+
*.py[cod]
|
|
25
|
+
*$py.class
|
|
26
|
+
|
|
27
|
+
# C extensions
|
|
28
|
+
*.so
|
|
29
|
+
|
|
30
|
+
# Distribution / packaging
|
|
31
|
+
.Python
|
|
32
|
+
build/
|
|
33
|
+
develop-eggs/
|
|
34
|
+
dist/
|
|
35
|
+
downloads/
|
|
36
|
+
eggs/
|
|
37
|
+
.eggs/
|
|
38
|
+
lib/
|
|
39
|
+
lib64/
|
|
40
|
+
parts/
|
|
41
|
+
sdist/
|
|
42
|
+
var/
|
|
43
|
+
wheels/
|
|
44
|
+
pip-wheel-metadata/
|
|
45
|
+
share/python-wheels/
|
|
46
|
+
.installed.cfg
|
|
47
|
+
*.egg
|
|
48
|
+
MANIFEST
|
|
49
|
+
|
|
50
|
+
# PyInstaller
|
|
51
|
+
# Usually these files are written by a python script from a template
|
|
52
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
53
|
+
*.manifest
|
|
54
|
+
*.spec
|
|
55
|
+
|
|
56
|
+
# Installer logs
|
|
57
|
+
pip-log.txt
|
|
58
|
+
pip-delete-this-directory.txt
|
|
59
|
+
|
|
60
|
+
# Unit test / coverage reports
|
|
61
|
+
junit.xml
|
|
62
|
+
htmlcov/
|
|
63
|
+
.tox/
|
|
64
|
+
.nox/
|
|
65
|
+
.coverage
|
|
66
|
+
.coverage.*
|
|
67
|
+
.cache
|
|
68
|
+
nosetests.xml
|
|
69
|
+
coverage/
|
|
70
|
+
coverage.xml
|
|
71
|
+
*.cover
|
|
72
|
+
.hypothesis/
|
|
73
|
+
.pytest_cache/
|
|
74
|
+
|
|
75
|
+
# Translations
|
|
76
|
+
*.mo
|
|
77
|
+
*.pot
|
|
78
|
+
|
|
79
|
+
# Scrapy stuff:
|
|
80
|
+
.scrapy
|
|
81
|
+
|
|
82
|
+
# Sphinx documentation
|
|
83
|
+
docs/_build/
|
|
84
|
+
|
|
85
|
+
# PyBuilder
|
|
86
|
+
target/
|
|
87
|
+
|
|
88
|
+
# pyenv
|
|
89
|
+
.python-version
|
|
90
|
+
|
|
91
|
+
# celery beat schedule file
|
|
92
|
+
celerybeat-schedule
|
|
93
|
+
|
|
94
|
+
# SageMath parsed files
|
|
95
|
+
*.sage.py
|
|
96
|
+
|
|
97
|
+
# Spyder project settings
|
|
98
|
+
.spyderproject
|
|
99
|
+
.spyproject
|
|
100
|
+
|
|
101
|
+
# Rope project settings
|
|
102
|
+
.ropeproject
|
|
103
|
+
|
|
104
|
+
# Mr Developer
|
|
105
|
+
.mr.developer.cfg
|
|
106
|
+
.project
|
|
107
|
+
.pydevproject
|
|
108
|
+
|
|
109
|
+
# mkdocs documentation
|
|
110
|
+
/site
|
|
111
|
+
|
|
112
|
+
# mypy
|
|
113
|
+
.mypy_cache/
|
|
114
|
+
.dmypy.json
|
|
115
|
+
dmypy.json
|
|
116
|
+
|
|
117
|
+
# Pyre type checker
|
|
118
|
+
.pyre/
|
|
119
|
+
|
|
120
|
+
# End of https://www.gitignore.io/api/python
|
|
121
|
+
|
|
122
|
+
# OSX files
|
|
123
|
+
.DS_Store
|
|
124
|
+
|
|
125
|
+
# Yarn cache
|
|
126
|
+
.yarn/
|
|
127
|
+
|
|
128
|
+
# VS Code
|
|
129
|
+
.vscode
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nodeLinker: node-modules
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Copyright (c) 2026, Afshin T. Darian
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
|
4
|
+
modification, are permitted provided that the following conditions are met:
|
|
5
|
+
|
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
7
|
+
list of conditions and the following disclaimer.
|
|
8
|
+
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
|
11
|
+
and/or other materials provided with the distribution.
|
|
12
|
+
|
|
13
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
may be used to endorse or promote products derived from this software
|
|
15
|
+
without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
18
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
19
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
21
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
23
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
24
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
25
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Onboarding Guide
|
|
2
|
+
|
|
3
|
+
This package is infrastructure for metrics collection in JupyterLab and
|
|
4
|
+
JupyterLite. It is not a complete analytics product by itself.
|
|
5
|
+
|
|
6
|
+
If you are new to the project, the most important thing to know is this:
|
|
7
|
+
|
|
8
|
+
1. Installing the package is not enough to observe data.
|
|
9
|
+
2. The default frontend collector is a no-op.
|
|
10
|
+
3. The dispatcher settings default to a state that blocks the built-in events.
|
|
11
|
+
|
|
12
|
+
To see useful metrics, you need two things at the same time:
|
|
13
|
+
|
|
14
|
+
1. Emissions enabled.
|
|
15
|
+
2. A consumer for those emissions.
|
|
16
|
+
|
|
17
|
+
For JupyterLab, the consumer can live in the frontend as a custom collector
|
|
18
|
+
plugin, or on the backend as a Jupyter Server event listener. For JupyterLite,
|
|
19
|
+
only the frontend path applies.
|
|
20
|
+
|
|
21
|
+
## Mental Model
|
|
22
|
+
|
|
23
|
+
The package has four moving parts.
|
|
24
|
+
|
|
25
|
+
1. The Python server extension `notebook_metrics` registers the event
|
|
26
|
+
schemas with Jupyter Server. It can also inject a `PageConfig` override from
|
|
27
|
+
a YAML file pointed to by `NOTEBOOK_METRICS_OVERRIDE`.
|
|
28
|
+
2. The frontend broadcasts plugin wires JupyterLab signals and browser events
|
|
29
|
+
into metrics emissions.
|
|
30
|
+
3. The frontend dispatcher plugin listens to the Jupyter events stream,
|
|
31
|
+
applies filtering, and forwards accepted events to a collector.
|
|
32
|
+
4. The default frontend collector plugin intentionally does nothing. It exists
|
|
33
|
+
so the package can load cleanly before you replace it.
|
|
34
|
+
|
|
35
|
+
That means there are two valid integration styles:
|
|
36
|
+
|
|
37
|
+
1. Frontend collection: provide your own `IMetrics.ICollector` plugin.
|
|
38
|
+
2. Backend collection: listen to the registered schema events on
|
|
39
|
+
`app.event_logger`.
|
|
40
|
+
|
|
41
|
+
The working examples in this repository follow both patterns:
|
|
42
|
+
|
|
43
|
+
1. Frontend filtering and dispatch are covered in
|
|
44
|
+
[src/**tests**/notebook_metrics.spec.ts](./src/__tests__/notebook_metrics.spec.ts).
|
|
45
|
+
2. Backend listener collection is demonstrated in
|
|
46
|
+
[notebook_metrics/tests/test_pass.py](./notebook_metrics/tests/test_pass.py)
|
|
47
|
+
and [ui-tests/event_capture_extension.py](./ui-tests/event_capture_extension.py).
|
|
48
|
+
|
|
49
|
+
## What Ships In The Box
|
|
50
|
+
|
|
51
|
+
The package emits four schema'd events.
|
|
52
|
+
|
|
53
|
+
1. `https://schema.notebook.link/metrics/command-executed/v1`
|
|
54
|
+
Fired when the JupyterLab command registry executes a command.
|
|
55
|
+
2. `https://schema.notebook.link/metrics/current-changed/v1`
|
|
56
|
+
Fired when the shell emits a non-null `currentChanged` value.
|
|
57
|
+
3. `https://schema.notebook.link/metrics/jupyter-error/v1`
|
|
58
|
+
Fired when notebook cell execution fails with a Jupyter error.
|
|
59
|
+
4. `https://schema.notebook.link/metrics/runtime-error/v1`
|
|
60
|
+
Fired for window-level `error` and `unhandledpromiserejection` events.
|
|
61
|
+
|
|
62
|
+
Today, all four built-in events are marked the same way:
|
|
63
|
+
|
|
64
|
+
1. `anonymous: false`
|
|
65
|
+
2. `sensitivity: high`
|
|
66
|
+
|
|
67
|
+
That has an important consequence for onboarding: if you leave the defaults in
|
|
68
|
+
place, none of the built-in events will pass the filter.
|
|
69
|
+
|
|
70
|
+
## First Successful Setup
|
|
71
|
+
|
|
72
|
+
This is the shortest path to a real signal in JupyterLab.
|
|
73
|
+
|
|
74
|
+
### 1. Install The Package
|
|
75
|
+
|
|
76
|
+
Install it with:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
python -m pip install notebook-metrics
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use `notebook-metrics` for installation, but `notebook_metrics` for Python
|
|
83
|
+
imports and the server extension name.
|
|
84
|
+
|
|
85
|
+
### 2. Enable Emissions
|
|
86
|
+
|
|
87
|
+
You can enable emissions either through JupyterLab user settings or through a
|
|
88
|
+
server-side page-config override.
|
|
89
|
+
|
|
90
|
+
For first-time evaluation, the override file is the clearest option because it
|
|
91
|
+
is explicit and wins over user settings.
|
|
92
|
+
|
|
93
|
+
Create a YAML file like this:
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
anonymous: false
|
|
97
|
+
disabled: false
|
|
98
|
+
excluded:
|
|
99
|
+
'https://schema.notebook.link/metrics/command-executed/v1': false
|
|
100
|
+
'https://schema.notebook.link/metrics/current-changed/v1': false
|
|
101
|
+
'https://schema.notebook.link/metrics/jupyter-error/v1': false
|
|
102
|
+
'https://schema.notebook.link/metrics/runtime-error/v1': false
|
|
103
|
+
sensitivity: high
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Then point `NOTEBOOK_METRICS_OVERRIDE` at it before starting JupyterLab.
|
|
107
|
+
|
|
108
|
+
Why this exact file matters:
|
|
109
|
+
|
|
110
|
+
1. `disabled: false` turns the dispatcher on.
|
|
111
|
+
2. `anonymous: false` allows the shipped non-anonymous events through.
|
|
112
|
+
3. `sensitivity: high` allows the shipped high-sensitivity events through.
|
|
113
|
+
4. `excluded` keeps each built-in schema enabled.
|
|
114
|
+
|
|
115
|
+
### 3. Choose A Consumer Path
|
|
116
|
+
|
|
117
|
+
At this point the package is allowed to emit, but you still need something to
|
|
118
|
+
observe or store the events.
|
|
119
|
+
|
|
120
|
+
Choose one of these paths:
|
|
121
|
+
|
|
122
|
+
1. If you want browser-side handling, add a custom frontend collector plugin.
|
|
123
|
+
2. If you want server-side handling, add a Jupyter Server listener.
|
|
124
|
+
|
|
125
|
+
## Path A: Frontend Collector
|
|
126
|
+
|
|
127
|
+
Use this when you want to forward metrics from the JupyterLab frontend to your
|
|
128
|
+
own service, local storage, or application-specific telemetry pipeline.
|
|
129
|
+
|
|
130
|
+
The collector contract is intentionally small:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
interface ICollector {
|
|
134
|
+
collect: (schema: string, event: IMetrics.Event<unknown>) => Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Your custom plugin needs to provide `IMetrics.ICollector`.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import type { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
142
|
+
import { IMetrics } from 'notebook-metrics';
|
|
143
|
+
|
|
144
|
+
const collector: JupyterFrontEndPlugin<IMetrics.ICollector> = {
|
|
145
|
+
id: 'acme-metrics:collector',
|
|
146
|
+
autoStart: true,
|
|
147
|
+
provides: IMetrics.ICollector,
|
|
148
|
+
activate: () => ({
|
|
149
|
+
collect: async (schema, event) => {
|
|
150
|
+
console.log('metric', schema, event.metrics);
|
|
151
|
+
// Replace this with your real sink.
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export default collector;
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Production note: disable the built-in no-op collector plugin
|
|
160
|
+
`notebook-metrics:collector` when your application ships a real one.
|
|
161
|
+
|
|
162
|
+
Good first smoke test:
|
|
163
|
+
|
|
164
|
+
1. Start JupyterLab with the permissive override shown above.
|
|
165
|
+
2. Load your collector plugin.
|
|
166
|
+
3. Execute a known command such as changing the JupyterLab theme.
|
|
167
|
+
4. Confirm your collector receives
|
|
168
|
+
`https://schema.notebook.link/metrics/command-executed/v1`.
|
|
169
|
+
|
|
170
|
+
## Path B: Backend Listener
|
|
171
|
+
|
|
172
|
+
Use this when you want to keep collection on the Jupyter Server side, or when
|
|
173
|
+
you want the server to fan out metrics to another system.
|
|
174
|
+
|
|
175
|
+
The server extension already registers the schemas. Your job is to attach a
|
|
176
|
+
listener to the server event logger.
|
|
177
|
+
|
|
178
|
+
This minimal server extension mirrors the test-only capture extension in this
|
|
179
|
+
repository.
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from notebook_metrics import schemas
|
|
183
|
+
|
|
184
|
+
PREFIX = 'https://schema.notebook.link/metrics'
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _jupyter_server_extension_points():
|
|
188
|
+
return [{'module': 'acme_metrics_listener'}]
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _load_jupyter_server_extension(app):
|
|
192
|
+
async def listener(logger, schema_id, data):
|
|
193
|
+
app.log.info('metric %s %s', schema_id, data.get('metrics', {}))
|
|
194
|
+
|
|
195
|
+
for schema in schemas:
|
|
196
|
+
app.event_logger.add_listener(
|
|
197
|
+
listener=listener,
|
|
198
|
+
schema_id=f'{PREFIX}/{schema}/v1',
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
You can see the same pattern in
|
|
203
|
+
[ui-tests/event_capture_extension.py](./ui-tests/event_capture_extension.py).
|
|
204
|
+
|
|
205
|
+
Good first smoke test:
|
|
206
|
+
|
|
207
|
+
1. Enable `notebook_metrics`.
|
|
208
|
+
2. Enable your listener extension.
|
|
209
|
+
3. Start JupyterLab with the permissive override.
|
|
210
|
+
4. Trigger a known event, such as a theme change.
|
|
211
|
+
5. Confirm your server logs or sink receive the matching schema URL.
|
|
212
|
+
|
|
213
|
+
## Configuration In Practice
|
|
214
|
+
|
|
215
|
+
The frontend dispatcher filter lives in the settings schema in
|
|
216
|
+
[schema/dispatcher.json](./schema/dispatcher.json). The useful keys are:
|
|
217
|
+
|
|
218
|
+
1. `disabled`: master switch. If this is `true`, nothing is forwarded.
|
|
219
|
+
2. `anonymous`: if this is `true`, only anonymous events are allowed.
|
|
220
|
+
3. `sensitivity`: allowed ceiling for event sensitivity.
|
|
221
|
+
4. `excluded`: per-schema booleans.
|
|
222
|
+
|
|
223
|
+
Configuration precedence is:
|
|
224
|
+
|
|
225
|
+
1. Built-in defaults.
|
|
226
|
+
2. JupyterLab user settings.
|
|
227
|
+
3. Page-config override from `NOTEBOOK_METRICS_OVERRIDE`.
|
|
228
|
+
|
|
229
|
+
The override wins. That is intentional. It lets a deployment operator lock the
|
|
230
|
+
policy down at the server layer.
|
|
231
|
+
|
|
232
|
+
One subtle point matters here: the built-in events are all currently
|
|
233
|
+
non-anonymous and high-sensitivity. If you leave `anonymous: true` or set
|
|
234
|
+
`sensitivity` below `high`, you will suppress the shipped events even when
|
|
235
|
+
`disabled` is `false`.
|
|
236
|
+
|
|
237
|
+
## Common Mistakes
|
|
238
|
+
|
|
239
|
+
These are the failures most likely to make a first integration feel broken.
|
|
240
|
+
|
|
241
|
+
1. Installing the package and expecting the default collector to save data.
|
|
242
|
+
2. Forgetting that the effective startup policy needs `disabled: false`.
|
|
243
|
+
3. Leaving `anonymous: true`, which filters out the shipped events.
|
|
244
|
+
4. Leaving `sensitivity` below `high`, which filters out the shipped events.
|
|
245
|
+
5. Expecting user settings to beat the server-side override file.
|
|
246
|
+
6. Forgetting to disable `notebook-metrics:collector` after shipping a
|
|
247
|
+
real frontend collector.
|
|
248
|
+
7. Expecting the backend listener path to work in JupyterLite.
|
|
249
|
+
|
|
250
|
+
## Where To Read Next
|
|
251
|
+
|
|
252
|
+
If you want the next layer of detail, these files are the most useful starting
|
|
253
|
+
points.
|
|
254
|
+
|
|
255
|
+
1. [README.md](./README.md) for installation and development workflows.
|
|
256
|
+
2. [src/plugins.ts](./src/plugins.ts) for the runtime wiring.
|
|
257
|
+
3. [src/metrics.ts](./src/metrics.ts) for the public TypeScript contract.
|
|
258
|
+
4. [schema/dispatcher.json](./schema/dispatcher.json) for the settings model.
|
|
259
|
+
5. [notebook_metrics/**init**.py](./notebook_metrics/__init__.py)
|
|
260
|
+
for server extension behavior and override loading.
|
|
261
|
+
6. [ui-tests/tests/notebook_metrics.spec.ts](./ui-tests/tests/notebook_metrics.spec.ts)
|
|
262
|
+
for an end-to-end backend collection example.
|
|
263
|
+
|
|
264
|
+
## A Good First Goal
|
|
265
|
+
|
|
266
|
+
If you are integrating this package for the first time, aim for this before you
|
|
267
|
+
do anything more ambitious:
|
|
268
|
+
|
|
269
|
+
1. Start JupyterLab with a permissive override.
|
|
270
|
+
2. Trigger one known event.
|
|
271
|
+
3. See one matching schema URL in your chosen sink.
|
|
272
|
+
|
|
273
|
+
Once that works, you can tighten the policy, narrow the `excluded` map, or swap
|
|
274
|
+
in a production collector.
|