hobots 1.3.5 → 1.3.6
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.
- package/README.md +35 -17
- package/dist/index.cjs +49 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -110
- package/dist/index.d.ts +123 -110
- package/dist/index.js +49 -9
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +2 -0
- package/dist/protocol.d.ts +2 -0
- package/docs/README.md +4 -1
- package/docs/api-reference.md +87 -11
- package/docs/concepts.md +440 -0
- package/docs/getting-started.md +17 -2
- package/docs/manager.md +36 -7
- package/docs/monitor.md +37 -3
- package/docs/protocol.md +3 -1
- package/package.json +1 -1
package/docs/monitor.md
CHANGED
|
@@ -6,7 +6,7 @@ Capability de telemetria: erros, performance, crons e uptime. Sempre ativa no `i
|
|
|
6
6
|
import * as Hobots from 'hobots';
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Todas as funções abaixo são no-op seguros se `Hobots.init()` não foi chamado (com aviso no console). Assinaturas completas em [Referência de API](./api-reference.md).
|
|
9
|
+
Todas as funções abaixo são no-op seguros se `Hobots.init()` não foi chamado (com aviso no console). Assinaturas completas em [Referência de API](./api-reference.md); o que cada conceito **é**, em [Conceitos](./concepts.md).
|
|
10
10
|
|
|
11
11
|
## init
|
|
12
12
|
|
|
@@ -39,8 +39,12 @@ Hobots.captureMessage('Lote processado com sucesso', 'info');
|
|
|
39
39
|
|
|
40
40
|
Ambas retornam o `event_id` (ou `undefined` se não inicializado). O segundo argumento é um [`CaptureHint`](./api-reference.md#capturehint) (`level`, `tags`, `extra`, `fingerprint`).
|
|
41
41
|
|
|
42
|
+
> **Atenção:** o `event_id` retornado **não é confirmação de envio** — se o evento foi descartado por amostragem ou por `beforeSend`, você recebe um id normalmente e nada foi enfileirado.
|
|
43
|
+
|
|
42
44
|
Erros **não tratados** (`uncaughtException` / `unhandledRejection`) são capturados e flushados automaticamente antes do processo sair — desligue com `captureUnhandled: false`.
|
|
43
45
|
|
|
46
|
+
Conceitos: [Evento](./concepts.md#evento) · [Level](./concepts.md#level-severity) · [Fingerprint](./concepts.md#fingerprint).
|
|
47
|
+
|
|
44
48
|
## Breadcrumbs
|
|
45
49
|
|
|
46
50
|
Trilha do que aconteceu antes do erro; enviada junto do próximo evento.
|
|
@@ -51,6 +55,8 @@ Hobots.addBreadcrumb({ category: 'nfe', message: 'Baixou XML da nota 123', level
|
|
|
51
55
|
|
|
52
56
|
O buffer é limitado por `maxBreadcrumbs` (default 100, mais antigos descartados).
|
|
53
57
|
|
|
58
|
+
Dois pontos que costumam surpreender: a lista **não é limpa** ao enviar um evento (o próximo evento leva as mesmas migalhas de novo), e ela é **global** — para uma trilha que não vaze, adicione dentro de um `withScope`. Conceito: [Breadcrumb](./concepts.md#breadcrumb).
|
|
59
|
+
|
|
54
60
|
## Escopo: tags, usuário, contexto, extras
|
|
55
61
|
|
|
56
62
|
Dados anexados a **todos** os eventos seguintes:
|
|
@@ -63,6 +69,14 @@ Hobots.setContext('vm', { cpu: 4, ram: '8GB' });
|
|
|
63
69
|
Hobots.setExtra('ultimoLote', 128);
|
|
64
70
|
```
|
|
65
71
|
|
|
72
|
+
Qual usar para quê: **tag** é rótulo curto e indexável (você vai filtrar por isso), **context** é grupo nomeado de dados que andam juntos (você vai ler), **extra** é depósito livre para o resto. Detalhes e critérios em [Tag](./concepts.md#tag) · [Context](./concepts.md#context) · [Extra](./concepts.md#extra).
|
|
73
|
+
|
|
74
|
+
Três comportamentos que valem saber:
|
|
75
|
+
|
|
76
|
+
- Tags podem vir de quatro lugares e a última vence: `init({ tags })` → scope → evento → `hint` da chamada.
|
|
77
|
+
- `setContext(nome, null)` **apaga** o grupo. O SDK já injeta os grupos `runtime` e `os` em todo evento.
|
|
78
|
+
- `setExtra` não é indexado — se você quiser filtrar por aquele campo, ele deveria ser uma tag.
|
|
79
|
+
|
|
66
80
|
Para um escopo **isolado** (sem vazar para o global), use `withScope`:
|
|
67
81
|
|
|
68
82
|
```js
|
|
@@ -72,8 +86,12 @@ Hobots.withScope((scope) => {
|
|
|
72
86
|
});
|
|
73
87
|
```
|
|
74
88
|
|
|
89
|
+
> **Atenção:** `withScope` é **síncrono** — ele troca o scope global e restaura no fim do callback. Se você der `await` lá dentro, o scope isolado vale para qualquer código que capturar eventos enquanto aquele `await` está pendente. Em código concorrente (várias runs em paralelo), passe as tags no `hint`: `captureException(error, { tags: { lote: '128' } })`. Conceito: [withScope](./concepts.md#withscope).
|
|
90
|
+
|
|
75
91
|
## Performance: transactions e spans
|
|
76
92
|
|
|
93
|
+
Uma **transaction** é uma unidade de trabalho nomeada e medida ("quanto minha rotina demorou"); os **spans** são as etapas dentro dela ("onde o tempo foi gasto"). Conceitos: [Transaction](./concepts.md#transaction) · [Span](./concepts.md#span).
|
|
94
|
+
|
|
77
95
|
```js
|
|
78
96
|
const tx = Hobots.startTransaction('processar-lote', 'rpa.job');
|
|
79
97
|
|
|
@@ -91,7 +109,11 @@ tx.finish(); // só aqui a transaction é enviada (respeitando tracesSampleRate)
|
|
|
91
109
|
|
|
92
110
|
- `startChild(op?, description?)` existe tanto em `Transaction` quanto em `Span` (aninhamento arbitrário).
|
|
93
111
|
- Métodos encadeáveis: `setStatus`, `setData` (span), `setTag`/`setName` (transaction).
|
|
94
|
-
- `finish()` na transaction fecha spans abertos e envia o payload; nada é enviado se ela não foi amostrada.
|
|
112
|
+
- `finish()` na transaction fecha spans abertos e envia o payload; nada é enviado se ela não foi amostrada. É **idempotente** — chamar duas vezes não envia duas.
|
|
113
|
+
- A decisão de amostragem acontece no **`startTransaction()`**, não no `finish()`. Esquecer o `finish()` de um span não perde o dado: ele é fechado no instante em que a transaction fecha.
|
|
114
|
+
- Uma transaction leva as tags do `init()` e as que você marcar com `tx.setTag()` — ela **não** herda as tags do scope.
|
|
115
|
+
|
|
116
|
+
Dentro de um handler do Manager não abra transaction: já existe uma em [`ctx.tx`](./concepts.md#transaction-de-run-ctxtx).
|
|
95
117
|
|
|
96
118
|
## Crons (check-ins)
|
|
97
119
|
|
|
@@ -113,6 +135,8 @@ const id = Hobots.checkIn({ monitorSlug: 'sync-notas', status: 'in_progress' });
|
|
|
113
135
|
Hobots.checkIn({ monitorSlug: 'sync-notas', status: 'ok', checkInId: id, durationMs: 1234 });
|
|
114
136
|
```
|
|
115
137
|
|
|
138
|
+
`withMonitor` **relança** a exceção depois de fechar o check-in como `error` e capturar o evento (com a tag `monitor: <slug>`) — o seu `try/catch` em volta continua funcionando igual. Conceito: [Check-in](./concepts.md#check-in).
|
|
139
|
+
|
|
116
140
|
## Heartbeat (uptime)
|
|
117
141
|
|
|
118
142
|
Bate "estou vivo" periodicamente; o servidor acusa o robô **offline** quando os batimentos param.
|
|
@@ -124,15 +148,25 @@ Hobots.init({
|
|
|
124
148
|
});
|
|
125
149
|
```
|
|
126
150
|
|
|
127
|
-
`heartbeat: true` usa os defaults. A identidade é o `instanceId` do `init()`. Campos em [HeartbeatOptions](./api-reference.md#heartbeatoptions).
|
|
151
|
+
`heartbeat: true` usa os defaults. A identidade é o `instanceId` do `init()`. Campos em [HeartbeatOptions](./api-reference.md#heartbeatoptions); conceito em [Heartbeat](./concepts.md#heartbeat).
|
|
152
|
+
|
|
153
|
+
O primeiro batimento sai **na hora** em que o `init()` roda — não depois do primeiro intervalo. O batimento também carrega o intervalo configurado: é assim que o servidor sabe quanto silêncio é normal antes de declarar o robô offline.
|
|
128
154
|
|
|
129
155
|
Essa identidade é a mesma que o Manager envia no poll (`agent.instance_id`) — os dois canais derivam do `instanceId` do `init()`, então o robô aparece como **um agente só** em Monitor → Agentes automaticamente.
|
|
130
156
|
|
|
131
157
|
## Flush e close
|
|
132
158
|
|
|
159
|
+
Nada é enviado na hora: cada evento, transaction, check-in e heartbeat entra numa **fila em memória** e sai em lote. É por isso que essas duas funções existem — quando o processo morre, a fila morre com ele. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
|
|
160
|
+
|
|
133
161
|
```js
|
|
134
162
|
await Hobots.flush(2000); // envia o que está em buffer, mantém o SDK vivo
|
|
135
163
|
await Hobots.close(2000); // para o Manager (se ativo) + heartbeat + flush final do transport
|
|
136
164
|
```
|
|
137
165
|
|
|
166
|
+
O `timeoutMs` é opcional nas duas — o default é 5s (veja [Tempos e intervalos](./api-reference.md#tempos-e-intervalos)). As duas devolvem `false` quando estouram o prazo, o que significa que o SDK parou de esperar, **não** que os dados foram perdidos: os envios em voo continuam tentando enquanto o processo existir.
|
|
167
|
+
|
|
138
168
|
Chame `close` antes do processo sair. Os timers do Monitor são `unref`'d, então a telemetria **não** segura o processo vivo sozinha (só o `start()` do Manager segura).
|
|
169
|
+
|
|
170
|
+
> **Atenção:** `close()` é **terminal**. Depois dele, todo evento, transaction, check-in ou heartbeat novo é **descartado** com aviso no console — não existe `reopen()`. Se o programa precisar voltar a emitir telemetria, chame `Hobots.init()` de novo.
|
|
171
|
+
|
|
172
|
+
> **Atenção:** o `timeoutMs` do `close()` é gasto **duas vezes, em sequência** — uma esperando as runs do Manager, outra no flush final. `close(15_000)` pode levar até ~30s no pior caso. Dimensione por aí se o seu SIGTERM tem prazo curto.
|
package/docs/protocol.md
CHANGED
|
@@ -40,7 +40,9 @@ Endpoint fixo `POST /v1/ingest` recebe **envelopes** JSON autenticados por Beare
|
|
|
40
40
|
|
|
41
41
|
Tipos de item: `event`, `transaction`, `check_in`, `heartbeat` (definidos em `hobots/protocol`).
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Um `transaction` pode carregar `run_id`: é assim que a [transaction de uma run do Manager](./concepts.md#transaction-de-run-ctxtx) (`ctx.tx`) é correlacionada à execução, e o que permite o app montar o waterfall de performance dentro da solicitação. Transactions abertas com `startTransaction()` não têm esse campo.
|
|
44
|
+
|
|
45
|
+
**Flush & retries:** o transport flusha por `flushIntervalMs` ou ao atingir `maxBatchSize`. Ladder de retry de 3 tentativas; respostas 4xx (exceto 429) são descartadas sem retry; a fila tem teto fixo e descarta os itens **mais antigos** ao encher. Todos os valores em [Tempos e intervalos](./api-reference.md#tempos-e-intervalos).
|
|
44
46
|
|
|
45
47
|
## Manager — polling e reporte
|
|
46
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hobots",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "SDK JavaScript da Hobots — captura de erros, transactions, check-ins de cron e heartbeats (Monitor) e execução remota de tarefas sob demanda (Manager) para RPAs e integrações. Um único import e um único init().",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|