Heim/Dokumente/Benutzerdefinierte Metriken
Vertrag über benutzerdefinierte Metriken
Mit benutzerdefinierten Metriken kann der eigene Dienst Ihrer Erweiterung alle wichtigen Zahlen vorantreiben dafür (Conversions, Umsatz, Backend-Zustand, Trichter) im selben Panel Das verfolgt bereits Installationen und den Zustand des Chrome Web Stores. Der Vertrag ist Metadatengesteuert und zweiflächig: Jede Metrik gibt an, wo und wie sie erfolgt erscheint sowohl im Dashboard als auch im Status Telegram, sodass das Panel erhalten bleibt ein generischer Renderer ohne produktspezifischen Code.
1. Wie es funktioniert (doppelte Oberfläche)
Ihr Dienst stellt einen Metrikendpunkt bereit. Ext Ops Panel ist der Client: it zieht diesen Endpunkt (niemals umgekehrt) und rendert den Antwort. Die Antwort steuert zwei Oberflächen gleichzeitig:
- Dashboard-Registerkarten in der Detailansicht der Erweiterung: Registerkarten, Abschnitte und metrische Renderarten.
- Telegram-Status: Logische Zeilen, die aus denselben Metriken bestehen und pro Metrik gefiltert und formatiert werden.
Das Panel führt Ihre Metriken mit den Basismetriken des Erstanbieters zusammen (Installationen / Deinstallationen / Neuinstallationen / Feedback / Chrome Web Store / Gesundheit), die im Reservat wohnen Base Tab und Telegram Zeile.
2. Der Endpunkt und die Authentifizierung
Das Panel ruft Ihren Endpunkt mit auf GET und erwartet die v2 Nutzlast als 200-Antwort. Zwei Pull-Modi haben die gleiche Form:
- Auf Anfrage: wird ausgelöst, wenn ein Benutzer Detail öffnet. Preis begrenzt auf höchstens 1 Anfrage pro Minute und Quelle, für alle Pläne, einschließlich Free.
- Überwachung: erstellt nach einem Zeitplan (nur Testversion/kostenpflichtig) die Telegram-Status- und Edge-Warnungen.
Die Authentifizierung ist eine davon keiner, Träger oder api_key_header. Geheimnisse werden im Ruhezustand verschlüsselt im Panel-Backend gespeichert und niemals weitergegeben zur Dashboard-Erweiterung. Wenn ein Zug fehlschlägt, wird das Panel ordnungsgemäß degradiert (letzter Snapshot oder ausgeblendet), ohne die Basismetriken zu beschädigen.
3. Nutzlaststruktur
Die Nutzlast der obersten Ebene enthält das Layout (Registerkarten, Abschnitte, Telegram Zeilen) und das Metrik-Array.
| Feld | Typ | Notizen |
|---|---|---|
schema_version | Zeichenfolge | Erforderlich. Muss "2.0" sein. |
generated_at | Zeichenfolge (Datum-Uhrzeit) | Wann die Nutzlast zusammengestellt wurde (Aktivitäts-/Leerlauferkennung). |
tabs | Tab[] | Dashboard-Registerkarten. Siehe Abschnitt 4. |
sections | Abschnitt[] | Gruppen von Metriken innerhalb einer Registerkarte (tab, id, title, order). |
telegram | TelegramMeta | header Vorlage + lines[]. Siehe Abschnitt 7. |
metrics | Metrisch[] | Die Metriken selbst. Siehe Abschnitte 5 und 6. |
4. Registerkarten und Registerkartensymbole
Ein Tab ist { id, title, order, icon? }. Das Reservierte
Base Die Registerkarte ist die eigene des Panels
(icon="layout-dashboard"); Ihr Service leistet den Rest. Wenn viele
Tabs sind geöffnet, der aktive Tab zeigt Symbol + Titel und die anderen werden eingeblendet
Nur Symbol (Titel bleibt im Tooltip und Arien-Label).
Der Wert icon ist eines von zwei Dingen:
- A Name des Lucide-Symbols im Kebab-Fall ASCII (entspricht
^[a-z][a-z0-9-]*$), z.B.trending-up. Ein wohlgeformtes Aber Ein nicht unterstützter Name wird auf das Standardsymbol (square) herabgestuft, sodass die Leiste nie unterbrochen wird. - A einzelnes Emoji, z.B. 💰 oder 🚀, gerendert als Text.
Das Panel enthält eine kuratierte Teilmenge von 37 Lucide-Namen (für das MV3-Paket schlank gehalten):
- Layout-Dashboard
- Aktivität
- Messgerät
- Schichten
- Stecker
- Dollarzeichen
- Banknote
- Geldbörse
- Kreditkarte
- Quittung
- Balkendiagramm-3
- Liniendiagramm
- Kreisdiagramm
- im Aufwärtstrend
- Abwärtstrend
- Benutzer
- Benutzer
- Warndreieck
- Glocke
- Uhr
- Git-Zweig
- Paket
- Kasten
- Datenbank
- Server
- CPU
- zappen
- Globus
- Puzzle
- Trichter
- Filter
- Quadrat
- Kreis
- Hash
- Prozent
- Etikett
- Flagge
5. Metrik: Wert + zwei Platzierungsblöcke
Eine Metrik enthält einen typisierten Wert plus zwei unabhängige Blöcke:
dashboard (wo und wie in der Erweiterung) und
telegram (wo und wie in der Nachricht). Entweder kann weggelassen werden oder
über show:false verborgen, sodass eine Metrik nur auf einer Oberfläche leben kann.
| Feld | Notizen |
|---|---|
id | Stabile Metrik-ID, eindeutig in der Nutzlast. |
kind | Datentyp (Abschnitt 5.1). Wählt aus, welche Wertefelder gelten. |
label | Kanonisches menschliches Etikett. |
value und Art-Felder | Nutzlastfelder hängen von kind ab (Abschnitt 5.1). |
severity | Einer von ok, info, warn, crit (wird Farbe/Emoji zugeordnet). |
shareable | Optionaler boolescher Wert, Standard true. Bei false ist die Metrik nur für den Besitzer bestimmt: Bei einem schreibgeschützten Projekt wird sie serverseitig entfernt und erreicht nie einen Beobachter/eine öffentliche Ansicht (Verwendung für Finanzmetriken). Regiert den Zugang, nicht die Platzierung. |
dashboard | { show, tab, section, order, name, render, options } (Abschnitt 5.2). |
telegram | { show, line, pos, format, sep, when } (Abschnitte 6 und 8). |
5.1. Arten (Datentyp + Nutzlast)
Arten sind ein offene Menge: Eine unbekannte Art wird vom Renderer ignoriert (aufwärtskompatibel).
| Art | Nutzlastfelder | Beispielanwendung |
|---|---|---|
number | value (+ optional delta, unit) | Installation / Feedback zählt |
delta | value, delta (rendert 1200 (+72)) | insgesamt (+heute) |
percent | value (0 bis 100) | Erfolgsquote des Motors |
duration | seconds oder minutes | p50/p95/Durchschnitt, Frische |
bytes | bytes oder kb | Ausgabegröße (~522 KB) |
rating | value, count | 5,0★ (1) |
money | value, currency, optional delta | MRR, ausgeben |
status | state + severity | Gesundheitsampel |
series | points:[{date,count}], optional Multi series:[{name,points}] | tägliche Installationen, aktive Benutzer |
intraday | series:[{name,intraday:[{minute,value}]}], optional step_min (Standard 15), tz | heute um 15-Minuten-Eimer |
hour_histogram | { weekdays:[...], start, end, tz } | Konvertierungen pro Stunde |
funnel | steps:[{key,label,value}] | Preise zur Kasse |
breakdown | items:[{label,value,unit?,sub?/money?}] | U-Boote nach Plan, nach Motor, nach Oberfläche |
list | items:[{text,count?,severity?}] | aktuelle Fehler |
text | value (Zeichenfolge) | Freitext |
5.2. Rendern (wie auf dem Dashboard angezeigt)
dashboard.render wählt das Bild aus (entspricht normalerweise kind,
kann aber abweichen, z.B. einen percent als badge anzeigen). Auch
eine offene Menge.
| machen | Suchen | Optionen (dashboard.options) |
|---|---|---|
kpi | Karte: Name + großer Wert + Delta | tone |
badge | Statuspille/Piktogramm nach Schweregrad | – |
chart | Liniendiagramm (Monat/Lebensdauer, gleitender 7-Durchschnitt, Hover) | series, defaultMode |
intraday | Heute nach Buckets (96 pro UTC Tag): gestapelte Balken oder geglättete Linien, Zeitachse HH:MM, Schwebeanzeige über die Serien hinweg | mode (bars | lines, Standard lines) |
hour_histogram | Stündliche Balken, gruppiert nach Wochentagen/Wochenende/nach Wochentag | series |
funnel | Schritte mit Umrechnung dazwischen | – |
breakdown | Horizontale kategoriale Balken mit Wert + Anteil am Gesamtwert | items |
table | Tabelle (z. B. Feedback) | columns |
text | Absatz / Inline | – |
status | Ampelstatus nach Schweregrad | – |
list | Liste der Elemente mit optionaler Anzahl/Schweregrad | – |
intraday vs. chart. Der chart
Achse ist täglich (points[].date = YYYY-MM-DD) und seine
Die Monatsansicht wird auf die letzten 30 Punkte aufgeteilt, sodass die heutigen 96 Buckets nicht darauf passen.
intraday ist das First-Party-Today-Diagramm, das als Vertragsart verfügbar ist: das
Dieselbe Konvention, bei der minute die Minuten ab Beginn des UTC-Tages zählt
(0, 15, …, 1425), aber die Reihen und Daten werden von der Quelle deklariert. Nur senden
nicht leere Eimer, die Platte verdichtet den Rest.
Ein leerer Bucket ist null, nicht 0. Für ein
Durchschnitt (z. B. mittlere Konvertierungszeit) eine Null wäre eine Lüge, so die Linie bricht
anstatt auf den Boden zu fallen. Ein fehlender Bucket und value: null sind vorhanden
Äquivalent: Die Linie bricht um, es wird kein Balken gezeichnet und in der Hover-Anzeige wird ein Strich angezeigt.
6. Das Panel ist Eigentümer der Palette
Diagramm- und Serienfarben werden zugewiesen durch das Gremium von der Marke
Tokens, nicht von der Quelle. options.series[] trägt nur die Identität
({key,label,order}); ein color-Feld in der Nutzlast ist
beratend und ignoriert. Semantische Schlüssel werden festen Token zugeordnet
(paid für Akzent, free für gedämpfte Neutralität,
failed/error zur Gefahr,
ready/success zum Erfolg); andere schlüssel nehmen die
kategorische Markenpalette positionell. Der Kontrast beträgt in beiden Fällen mindestens 4,5:1
Themen. Dies schützt die Marke vor willkürlicher Fremdverhexung.
7. Telegram-Vorlagen
telegram.header ist der Nachrichtenheader;
telegram.lines[] sind logische Zeilen
({ id, order, prefix, when }). Der Komponist sammelt jede Metrik
mit einem gegebenen telegram.line, filtert nach when, sortiert nach
pos, rendert jedes über seine Vorlage format und verknüpft
sie mit dem sep jeder Metrik. Die Zeile prefix wird gedruckt
zuerst. Alles ist Klartext.
| Platzhalter | Ausgabe |
|---|---|
{value} | Nach Art (Anzahl 1,200; Prozent 99%) |
{value:k} | 1.2k / 3.0M (kompakt) |
{delta:+} | +72 / -3 |
{value:pct} | 99% |
{seconds:dur} | 28s / 5m 47s |
{minutes:age} | 45m / 2h 30m / never |
{bytes:size} | ~522KB / 1.4MB |
{value}★ ({count}) | 5.0★ (1) |
{sev} | Schweregrad-Emoji: 🟢 ok, 🟡 warnen, 🔴 kritisch, ⚪ untätig |
{trend} | ↗ / ↘ (±5pp vs. 7d) |
8. Sichtbedingungen (wann)
when steuert, ob ein Metrikfeld (oder eine ganze Telegram-Zeile)
zeigt. Werte:
| Wann | Zeigt das Feld an |
|---|---|
always | Immer (Standard). |
nonzero | Nur wenn der Wert nicht 0 / leer ist. |
severity>=warn | Nur wenn der Schweregrad „Warnung“ oder „Kritisch“ ist. |
changed | Nur wenn es sich seit dem vorherigen Schnappschuss geändert hat. |
Unbekannte when-Werte verhalten sich wie always (aufwärtskompatibel).
9. Beispielnutzlast
{
"schema_version": "2.0",
"generated_at": "2026-07-02T23:17:30Z",
"tabs": [
{ "id": "conv", "title": "Conversions", "order": 1, "icon": "trending-up" }
],
"sections": [
{ "tab": "conv", "id": "by_hour", "title": "By hour", "order": 0 }
],
"telegram": {
"header": "{name} • {cws.users} • {cws.rating}★ ({cws.rating_count})",
"lines": [
{ "id": "base", "order": 0 },
{ "id": "conv", "order": 1, "prefix": "{sev} Conv " }
]
},
"metrics": [
{
"id": "conv_today",
"kind": "number",
"label": "Conversions today",
"value": 254,
"severity": "ok",
"shareable": true,
"dashboard": {
"show": true,
"tab": "conv", "section": "by_hour", "order": 10,
"name": "Today", "render": "kpi", "options": {}
},
"telegram": {
"show": true,
"line": "conv", "pos": 20,
"format": "today {value}", "sep": " • ", "when": "always"
}
}
]
}10. Der maschinenlesbare Vertrag
Die formale, importierbare Beschreibung dieses Endpunkts ist die Datei OpenAPI 3.1. Es trägt die gleiche Vertragsversion (2.0.0) und ist die einzige kanonische Version Maschinenartefakt, das sprachübergreifend geteilt wird.