hobots 1.3.4 → 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 +37 -19
- 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 +3 -1
- package/dist/protocol.d.ts +3 -1
- 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/dist/protocol.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/protocol.ts"],"sourcesContent":["/**\n * Tipos do protocolo de ingestão do Hobots Monitor (SDK → servidor).\n *\n * Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:\n * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`\n * contra estes tipos (importados de `hobots/protocol`).\n */\n\n// Wire format do Manager (agente ↔ servidor) — reexportado aqui para o app\n// consumir tudo de `hobots/protocol`.\nexport type {\n ManagerRunStatus,\n ManagerRunUpdateStatus,\n RunLogLevel,\n RunLogEntry,\n ManagerAgentInfo,\n ManagerPollRequest,\n ManagerRunDescriptor,\n ManagerPollResponse,\n ManagerRunError,\n ManagerRunUpdateRequest,\n ManagerRunUpdateResponse,\n} from './manager/protocol';\n\nexport type Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug';\n\n/** Frames em ordem innermost-first (mesma ordem impressa pelo V8). */\nexport interface StackFrame {\n function?: string;\n filename?: string;\n lineno?: number;\n colno?: number;\n in_app: boolean;\n}\n\nexport interface Breadcrumb {\n /** ISO 8601 */\n timestamp: string;\n type?: string;\n category?: string;\n message?: string;\n level?: Severity;\n data?: Record<string, unknown>;\n}\n\nexport interface ExceptionData {\n type: string;\n value: string;\n stacktrace?: { frames: StackFrame[] };\n}\n\nexport interface EventUser {\n id?: string;\n username?: string;\n email?: string;\n}\n\nexport interface EventPayload {\n /** uuid v4 sem hífens (32 hex), gerado pelo SDK */\n event_id: string;\n /** ISO 8601 */\n timestamp: string;\n level: Severity;\n message?: string;\n exception?: ExceptionData;\n /** Override de agrupamento; quando ausente o servidor calcula pelo stack trace */\n fingerprint?: string[];\n breadcrumbs?: Breadcrumb[];\n tags?: Record<string, string>;\n user?: EventUser;\n contexts?: Record<string, Record<string, unknown>>;\n extra?: Record<string, unknown>;\n release?: string;\n environment?: string;\n}\n\nexport interface SpanData {\n /** 16 hex */\n span_id: string;\n parent_span_id?: string;\n op?: string;\n description?: string;\n status?: string;\n /** ISO 8601 */\n start_timestamp: string;\n /** ISO 8601 (fim do span) */\n timestamp: string;\n data?: Record<string, unknown>;\n}\n\nexport interface TransactionPayload {\n event_id: string;\n name: string;\n op?: string;\n status: string;\n start_timestamp: string;\n timestamp: string;\n spans: SpanData[];\n tags?: Record<string, string>;\n release?: string;\n environment?: string;\n}\n\nexport type CheckInStatus = 'in_progress' | 'ok' | 'error';\n\nexport interface CheckInPayload {\n /** Mesmo id no par in_progress → ok/error para casar início e fim */\n check_in_id: string;\n monitor_slug: string;\n status: CheckInStatus;\n duration_ms?: number;\n /** Expressão cron — permite o servidor criar o monitor automaticamente (upsert) */\n schedule?: string;\n timezone?: string;\n environment?: string;\n release?: string;\n}\n\nexport interface HeartbeatPayload {\n instance_id: string;\n name?: string;\n interval_ms: number;\n /** ISO 8601 */\n timestamp: string;\n metadata?: Record<string, unknown>;\n release?: string;\n}\n\nexport type EnvelopeItem =\n | { type: 'event'; payload: EventPayload }\n | { type: 'transaction'; payload: TransactionPayload }\n | { type: 'check_in'; payload: CheckInPayload }\n | { type: 'heartbeat'; payload: HeartbeatPayload };\n\nexport interface Envelope {\n sdk: { name: string; version: string };\n /** ISO 8601 */\n sent_at: string;\n items: EnvelopeItem[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/protocol.ts"],"sourcesContent":["/**\n * Tipos do protocolo de ingestão do Hobots Monitor (SDK → servidor).\n *\n * Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:\n * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`\n * contra estes tipos (importados de `hobots/protocol`).\n */\n\n// Wire format do Manager (agente ↔ servidor) — reexportado aqui para o app\n// consumir tudo de `hobots/protocol`.\nexport type {\n ManagerRunStatus,\n ManagerRunUpdateStatus,\n RunLogLevel,\n RunLogEntry,\n ManagerAgentInfo,\n ManagerPollRequest,\n ManagerRunDescriptor,\n ManagerPollResponse,\n ManagerRunError,\n ManagerRunUpdateRequest,\n ManagerRunUpdateResponse,\n} from './manager/protocol';\n\nexport type Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug' | 'success';\n\n/** Frames em ordem innermost-first (mesma ordem impressa pelo V8). */\nexport interface StackFrame {\n function?: string;\n filename?: string;\n lineno?: number;\n colno?: number;\n in_app: boolean;\n}\n\nexport interface Breadcrumb {\n /** ISO 8601 */\n timestamp: string;\n type?: string;\n category?: string;\n message?: string;\n level?: Severity;\n data?: Record<string, unknown>;\n}\n\nexport interface ExceptionData {\n type: string;\n value: string;\n stacktrace?: { frames: StackFrame[] };\n}\n\nexport interface EventUser {\n id?: string;\n username?: string;\n email?: string;\n}\n\nexport interface EventPayload {\n /** uuid v4 sem hífens (32 hex), gerado pelo SDK */\n event_id: string;\n /** ISO 8601 */\n timestamp: string;\n level: Severity;\n message?: string;\n exception?: ExceptionData;\n /** Override de agrupamento; quando ausente o servidor calcula pelo stack trace */\n fingerprint?: string[];\n breadcrumbs?: Breadcrumb[];\n tags?: Record<string, string>;\n user?: EventUser;\n contexts?: Record<string, Record<string, unknown>>;\n extra?: Record<string, unknown>;\n release?: string;\n environment?: string;\n}\n\nexport interface SpanData {\n /** 16 hex */\n span_id: string;\n parent_span_id?: string;\n op?: string;\n description?: string;\n status?: string;\n /** ISO 8601 */\n start_timestamp: string;\n /** ISO 8601 (fim do span) */\n timestamp: string;\n data?: Record<string, unknown>;\n}\n\nexport interface TransactionPayload {\n event_id: string;\n name: string;\n op?: string;\n status: string;\n start_timestamp: string;\n timestamp: string;\n spans: SpanData[];\n tags?: Record<string, string>;\n release?: string;\n environment?: string;\n /** Correlaciona esta transaction a uma execução do Manager (ctx.tx dentro de um task handler) */\n run_id?: string;\n}\n\nexport type CheckInStatus = 'in_progress' | 'ok' | 'error';\n\nexport interface CheckInPayload {\n /** Mesmo id no par in_progress → ok/error para casar início e fim */\n check_in_id: string;\n monitor_slug: string;\n status: CheckInStatus;\n duration_ms?: number;\n /** Expressão cron — permite o servidor criar o monitor automaticamente (upsert) */\n schedule?: string;\n timezone?: string;\n environment?: string;\n release?: string;\n}\n\nexport interface HeartbeatPayload {\n instance_id: string;\n name?: string;\n interval_ms: number;\n /** ISO 8601 */\n timestamp: string;\n metadata?: Record<string, unknown>;\n release?: string;\n}\n\nexport type EnvelopeItem =\n | { type: 'event'; payload: EventPayload }\n | { type: 'transaction'; payload: TransactionPayload }\n | { type: 'check_in'; payload: CheckInPayload }\n | { type: 'heartbeat'; payload: HeartbeatPayload };\n\nexport interface Envelope {\n sdk: { name: string; version: string };\n /** ISO 8601 */\n sent_at: string;\n items: EnvelopeItem[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/dist/protocol.d.cts
CHANGED
|
@@ -8,7 +8,7 @@ export { ManagerAgentInfo, ManagerPollRequest, ManagerPollResponse, ManagerRunDe
|
|
|
8
8
|
* contra estes tipos (importados de `hobots/protocol`).
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
type Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug';
|
|
11
|
+
type Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug' | 'success';
|
|
12
12
|
/** Frames em ordem innermost-first (mesma ordem impressa pelo V8). */
|
|
13
13
|
interface StackFrame {
|
|
14
14
|
function?: string;
|
|
@@ -80,6 +80,8 @@ interface TransactionPayload {
|
|
|
80
80
|
tags?: Record<string, string>;
|
|
81
81
|
release?: string;
|
|
82
82
|
environment?: string;
|
|
83
|
+
/** Correlaciona esta transaction a uma execução do Manager (ctx.tx dentro de um task handler) */
|
|
84
|
+
run_id?: string;
|
|
83
85
|
}
|
|
84
86
|
type CheckInStatus = 'in_progress' | 'ok' | 'error';
|
|
85
87
|
interface CheckInPayload {
|
package/dist/protocol.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { ManagerAgentInfo, ManagerPollRequest, ManagerPollResponse, ManagerRunDe
|
|
|
8
8
|
* contra estes tipos (importados de `hobots/protocol`).
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
type Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug';
|
|
11
|
+
type Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug' | 'success';
|
|
12
12
|
/** Frames em ordem innermost-first (mesma ordem impressa pelo V8). */
|
|
13
13
|
interface StackFrame {
|
|
14
14
|
function?: string;
|
|
@@ -80,6 +80,8 @@ interface TransactionPayload {
|
|
|
80
80
|
tags?: Record<string, string>;
|
|
81
81
|
release?: string;
|
|
82
82
|
environment?: string;
|
|
83
|
+
/** Correlaciona esta transaction a uma execução do Manager (ctx.tx dentro de um task handler) */
|
|
84
|
+
run_id?: string;
|
|
83
85
|
}
|
|
84
86
|
type CheckInStatus = 'in_progress' | 'ok' | 'error';
|
|
85
87
|
interface CheckInPayload {
|
package/docs/README.md
CHANGED
|
@@ -11,6 +11,9 @@ O SDK expõe **duas capabilities** autenticadas pelo **mesmo Client Secret do pr
|
|
|
11
11
|
|
|
12
12
|
## Páginas
|
|
13
13
|
|
|
14
|
+
Se termos como transaction, span, breadcrumb, tag, context, extra, flush e close ainda não são familiares, comece por **Conceitos** — as outras páginas assumem esse vocabulário.
|
|
15
|
+
|
|
16
|
+
- [Conceitos](./concepts.md) — o vocabulário: o que cada coisa é, por que existe e quando escolher uma em vez da outra.
|
|
14
17
|
- [Getting started](./getting-started.md) — instalação, Client Secret, o `init` único, Monitor e Manager.
|
|
15
18
|
- [Monitor](./monitor.md) — erros, breadcrumbs, escopo, transactions/spans, crons e heartbeat.
|
|
16
19
|
- [Manager](./manager.md) — registro de handlers, `RunContext`, cancelamento, concorrência, idempotência.
|
|
@@ -36,7 +39,7 @@ Hobots.init({
|
|
|
36
39
|
|
|
37
40
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
38
41
|
ctx.log.info(`processando lote ${params.lote}…`);
|
|
39
|
-
|
|
42
|
+
ctx.log.info('12 notas processadas'); // o retorno do handler é ignorado — reporte por log
|
|
40
43
|
});
|
|
41
44
|
Hobots.start(); // mantém o processo vivo aguardando execuções
|
|
42
45
|
```
|
package/docs/api-reference.md
CHANGED
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
| --- | --- | --- |
|
|
18
18
|
| `init` | `init(options: InitOptions): void` | — |
|
|
19
19
|
| `getClient` | `getClient(): Client \| undefined` | cliente atual |
|
|
20
|
-
| `captureException` | `captureException(error: unknown, hint?: CaptureHint)` | `string \| undefined` (event_id) |
|
|
21
|
-
| `captureMessage` | `captureMessage(message: string, level?: Severity, hint?: CaptureHint)` | `string \| undefined` |
|
|
20
|
+
| `captureException` | `captureException(error: unknown, hint?: CaptureHint)` | `string \| undefined` (event_id — **não** é confirmação de envio) |
|
|
21
|
+
| `captureMessage` | `captureMessage(message: string, level?: Severity, hint?: CaptureHint)` | `string \| undefined` (idem) |
|
|
22
22
|
| `addBreadcrumb` | `addBreadcrumb(crumb: BreadcrumbInput): void` | — |
|
|
23
23
|
| `setTag` / `setTags` | `setTag(key, value)` · `setTags(tags)` | — |
|
|
24
24
|
| `setUser` | `setUser(user: EventUser \| null): void` | — |
|
|
@@ -28,8 +28,29 @@
|
|
|
28
28
|
| `startTransaction` | `startTransaction(name: string, op?: string): Transaction` | transaction |
|
|
29
29
|
| `checkIn` | `checkIn(options: CheckInOptions): string \| undefined` | check_in_id |
|
|
30
30
|
| `withMonitor` | `withMonitor<T>(slug: string, fn: () => T \| Promise<T>, options?: WithMonitorOptions): Promise<T>` | retorno de `fn` |
|
|
31
|
-
| `flush` | `flush(timeoutMs
|
|
32
|
-
| `close` | `close(timeoutMs
|
|
31
|
+
| `flush` | `flush(timeoutMs = 5_000): Promise<boolean>` | enviou tudo dentro do prazo? |
|
|
32
|
+
| `close` | `close(timeoutMs = 5_000): Promise<boolean>` | para o Manager (aguarda runs) + heartbeat + flush final do transport |
|
|
33
|
+
|
|
34
|
+
### O que cada função faz
|
|
35
|
+
|
|
36
|
+
Os conceitos por trás dessas chamadas estão em [Conceitos](./concepts.md); aqui está o que cada uma **faz** e o que **devolve**.
|
|
37
|
+
|
|
38
|
+
- **`init(options)`** — cria o cliente, instala os handlers globais de erro (a menos que `captureUnhandled: false`), inicia o heartbeat se configurado e cria o agente do Manager se `manager` foi passado. Chamar de novo **substitui** o cliente e o agente (os handlers registrados com `register` são preservados; o [scope](./concepts.md#scope) **não** é limpo). Chame uma vez, o mais cedo possível.
|
|
39
|
+
- **`getClient()`** — devolve o cliente atual ou `undefined` se o `init()` nunca rodou. Útil para checar se o SDK está ativo.
|
|
40
|
+
- **`captureException(error, hint?)`** — monta um [evento](./concepts.md#evento) a partir da exceção (tipo, mensagem, stack trace), mescla o scope e enfileira. O `level` é `error` a menos que você passe outro no `hint`.
|
|
41
|
+
- **`captureMessage(message, level = 'info', hint?)`** — mesma coisa, sem exceção: um evento só com texto. Bom para marcos (`'success'`) e avisos que não são erro.
|
|
42
|
+
> **Atenção:** as duas devolvem um `event_id` **mesmo quando o evento foi descartado** por [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) ou por [`beforeSend`](./concepts.md#beforesend). O retorno não prova que algo foi enviado — só é `undefined` quando o `init()` não foi chamado.
|
|
43
|
+
- **`addBreadcrumb(crumb)`** — adiciona uma migalha à trilha do [scope](./concepts.md#scope) global. Todos os campos são opcionais menos o `timestamp`, que o SDK preenche. A lista **não** é limpa ao enviar um evento; ela só descarta as mais antigas ao estourar `maxBreadcrumbs`. Conceito: [Breadcrumb](./concepts.md#breadcrumb).
|
|
44
|
+
- **`setTag(key, value)` / `setTags(tags)`** — grava [tags](./concepts.md#tag) no scope global; valem para todos os eventos seguintes. Só `string` → `string`. Precedência: `init.tags` → scope → evento → `hint`.
|
|
45
|
+
- **`setUser(user | null)`** — define quem está operando (`id`, `username`, `email`). `null` remove.
|
|
46
|
+
- **`setContext(name, ctx | null)`** — define um [context](./concepts.md#context) nomeado. Passar `null` **apaga o grupo inteiro**. Os grupos `runtime` e `os` são injetados pelo SDK em todo evento.
|
|
47
|
+
- **`setExtra(key, value)`** — anexa um dado livre, sem estrutura e sem índice. Conceito e critério de escolha em [Extra](./concepts.md#extra).
|
|
48
|
+
- **`withScope(cb)`** — roda o callback com um **clone** do scope e restaura o original no fim; devolve o que o callback devolver. É **síncrono** — um `await` dentro do callback não isola de código concorrente. Conceito: [withScope](./concepts.md#withscope).
|
|
49
|
+
- **`startTransaction(name, op?)`** — abre uma [transaction](./concepts.md#transaction) de performance. A decisão de [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) acontece **aqui**, não no `finish()`. Nada é enviado até o `finish()`. Dentro de um handler do Manager, use [`ctx.tx`](./concepts.md#transaction-de-run-ctxtx) em vez desta.
|
|
50
|
+
- **`checkIn(options)`** — envia um [check-in](./concepts.md#check-in) avulso e devolve o `check_in_id`. Reaproveite o id do `in_progress` para fechar a execução com `ok`/`error`.
|
|
51
|
+
- **`withMonitor(slug, fn, options?)`** — envolve `fn` no par de check-ins (`in_progress` → `ok`/`error`) medindo a duração, e devolve o que `fn` devolver. Em caso de erro, fecha como `error`, captura o evento com a tag `monitor: <slug>` e **relança** a exceção. Passe `schedule` para o servidor criar/atualizar o monitor sozinho e detectar execução perdida.
|
|
52
|
+
- **`flush(timeoutMs = 5_000)`** → `Promise<boolean>` — empurra a fila do transport e aguarda os envios em andamento. `true` = tudo saiu no prazo; `false` = o SDK parou de esperar (os envios em voo seguem tentando). O SDK **continua utilizável** depois. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
|
|
53
|
+
- **`close(timeoutMs = 5_000)`** → `Promise<boolean>` — encerra tudo na ordem agente → heartbeat → flush final. O `timeoutMs` é gasto **duas vezes** (espera das runs, depois flush). Depois do `close()` o transport está fechado e todo item novo é descartado com aviso no console; não há `reopen()`. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
|
|
33
54
|
|
|
34
55
|
Classes exportadas: `Client`, `Scope`, `Transaction`, `Span`. Função `resolveConfig({ clientSecret }): ResolvedConfig` — resolve a credencial nos endpoints (constante `DEFAULT_BASE_URL = 'https://api2.hobots.app'`, em `src/config.ts`; em desenvolvimento a env `HOBOTS_API_URL` sobrescreve a URL base):
|
|
35
56
|
|
|
@@ -42,11 +63,14 @@ interface ResolvedConfig {
|
|
|
42
63
|
}
|
|
43
64
|
```
|
|
44
65
|
|
|
45
|
-
### Métodos de `Transaction` / `Span`
|
|
66
|
+
### Métodos de `Transaction` / `Span` / `Scope`
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- `
|
|
68
|
+
Todos encadeáveis, exceto `finish()` e `toJSON()`.
|
|
69
|
+
|
|
70
|
+
- **`Transaction`** — `startChild(op?, description?) → Span` abre um [span](./concepts.md#span) direto; `setTag(k, v)` marca a transaction (tags de scope **não** são herdadas); `setStatus(s)` (default `'ok'`); `setName(n)` renomeia antes do envio; `finish()` fecha os spans abertos, monta o payload e envia — é **idempotente** e não envia nada se a transaction não foi amostrada.
|
|
71
|
+
- **`Span`** — `startChild(op?, description?) → Span` aninha um filho (profundidade arbitrária); `setStatus(s)` (default `'ok'`); `setData(k, v)` anexa dados só àquele span; `finish()` marca o fim — **opcional**, porque o `finish()` da transaction fecha o que ficou aberto; `toJSON()` serializa no formato do wire.
|
|
72
|
+
- **`Scope`** — `setTag`/`setTags`/`setUser`/`setContext`/`setExtra`/`setExtras`/`setLevel`/`setFingerprint`/`addBreadcrumb`/`clearBreadcrumbs`/`clone`. Alcançável via [`withScope`](./concepts.md#withscope). `setContext(name, null)` apaga o grupo; `setUser(null)` remove o usuário.
|
|
73
|
+
> **Atenção:** `setLevel` **não tem efeito** em `captureException` (que já grava `error`) nem em `captureMessage` (que já grava `info`) — os dois definem o level do evento antes de o scope ser consultado. Use o `hint`.
|
|
50
74
|
|
|
51
75
|
---
|
|
52
76
|
|
|
@@ -56,9 +80,15 @@ Habilitado com `manager: true` (ou `ManagerOptions`) no `init()` único. Todas e
|
|
|
56
80
|
|
|
57
81
|
| Função | Assinatura |
|
|
58
82
|
| --- | --- |
|
|
59
|
-
| `register` | `register<P
|
|
83
|
+
| `register` | `register<P>(task: string, handler: ManagerTaskHandler<P>): void` |
|
|
60
84
|
| `start` | `start(): void` — lança se o `init()` não configurou `manager` ou sem tasks registradas |
|
|
61
|
-
| `stop` | `stop(timeoutMs
|
|
85
|
+
| `stop` | `stop(timeoutMs = 30_000): Promise<boolean>` — para só o Manager; a telemetria continua |
|
|
86
|
+
|
|
87
|
+
### O que cada função faz
|
|
88
|
+
|
|
89
|
+
- **`register(task, handler)`** — associa um handler ao `task_slug` configurado no formulário do app. Registre **antes** de `start()`; pode ser chamado antes do `init()`. Registrar o mesmo `task` duas vezes **sobrescreve** o handler (com aviso no console). Se o `init()` não habilitou o Manager, o SDK avisa e não faz nada. Tipagem dos params: `register<{ lote: number }>(…)`.
|
|
90
|
+
- **`start()`** — começa o polling. **Mantém o processo vivo** até `stop()`/`close()` — o timer não é `unref`'d, ao contrário dos do Monitor. Lança se o `init()` não configurou `manager` ou se nenhuma task foi registrada. Também instala os handlers de saída (SIGINT/SIGTERM/erro fatal) que reportam as runs ativas como `AgentTerminated`, a menos que `installExitHandlers: false`.
|
|
91
|
+
- **`stop(timeoutMs = 30_000)`** → `Promise<boolean>` — encerra o polling e aguarda as [runs](./concepts.md#run) ativas terminarem. Para **só o Manager**: a telemetria (heartbeat, captura de erros) continua funcionando. Devolve `false` se estourou o timeout — as runs que ainda estavam rodando são reportadas como `AgentTerminated`. Para encerrar tudo, use [`close()`](./concepts.md#fila-flush-e-close).
|
|
62
92
|
|
|
63
93
|
Classes/erros exportados: `ManagerAgent`, `ManagerApi`, `ManagerApiError`.
|
|
64
94
|
|
|
@@ -88,6 +118,8 @@ No poll, o agente se identifica com `ManagerAgentInfo` (`hobots/protocol`): o ca
|
|
|
88
118
|
| `flushIntervalMs` | `number` | `2000` | intervalo do flush automático do transport |
|
|
89
119
|
| `maxBatchSize` | `number` | `10` | itens por envelope antes do flush imediato |
|
|
90
120
|
|
|
121
|
+
O teto da fila do transport (200 itens; ao encher, o **mais antigo** é descartado com aviso) é interno — **não** é opção do `init()`. Conceitos por trás dessas opções: [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate), [breadcrumbs](./concepts.md#breadcrumb), [instanceId](./concepts.md#instanceid), [release e environment](./concepts.md#release-e-environment), [beforeSend](./concepts.md#beforesend).
|
|
122
|
+
|
|
91
123
|
### HeartbeatOptions
|
|
92
124
|
|
|
93
125
|
| Opção | Tipo | Default | Descrição |
|
|
@@ -105,7 +137,7 @@ No poll, o agente se identifica com `ManagerAgentInfo` (`hobots/protocol`): o ca
|
|
|
105
137
|
| `extra` | `Record<string,unknown>` | dados extras |
|
|
106
138
|
| `fingerprint` | `string[]` | agrupamento manual |
|
|
107
139
|
|
|
108
|
-
`Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug'`.
|
|
140
|
+
`Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug' | 'success'`. O que cada nível significa (e por que `'success'` existe) em [Level](./concepts.md#level-severity).
|
|
109
141
|
|
|
110
142
|
### CheckInOptions
|
|
111
143
|
|
|
@@ -149,8 +181,52 @@ interface RunContext {
|
|
|
149
181
|
runId: string;
|
|
150
182
|
task: string;
|
|
151
183
|
log(level: 'debug' | 'info' | 'warning' | 'error', message: string): void;
|
|
184
|
+
tx: Transaction; // transaction desta run — correlacionada e finalizada pelo SDK
|
|
152
185
|
signal: AbortSignal;
|
|
153
186
|
throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
|
|
154
187
|
sleep(ms: number): Promise<void>; // espera cancelável — rejeita com RunCanceled no abort
|
|
155
188
|
}
|
|
156
189
|
```
|
|
190
|
+
|
|
191
|
+
- **`runId` / `task`** — identificam a execução; úteis para correlacionar com os seus próprios logs.
|
|
192
|
+
- **`log(level, message)`** — enfileira uma linha de log enviada ao app em PATCHes incrementais, e **também imprime no terminal local**. Conceito: [Run](./concepts.md#run).
|
|
193
|
+
- **`tx`** — a [transaction de performance da run](./concepts.md#transaction-de-run-ctxtx). Use `ctx.tx.startChild(op, description)` para medir as etapas; **não** chame `finish()` nela nem abra uma transaction própria com `startTransaction()`.
|
|
194
|
+
- **`signal`** — `AbortSignal` que dispara em cancelamento no app, timeout ou shutdown.
|
|
195
|
+
- **`throwIfCanceled()`** — o ponto de parada de uma linha: lança `RunCanceled` se o `signal` já disparou.
|
|
196
|
+
- **`sleep(ms)`** — espera que respeita o `signal` (rejeita com `RunCanceled` em vez de dormir até o fim). Use no lugar do seu `sleep` em esperas longas.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Tempos e intervalos
|
|
201
|
+
|
|
202
|
+
Todos os prazos do SDK num lugar só. A coluna **Onde configura** diz se o valor é seu ou fixo — o que está com `—` é comportamento do SDK ou do servidor e não se muda pelo `init()`.
|
|
203
|
+
|
|
204
|
+
### Monitor — envio de telemetria
|
|
205
|
+
|
|
206
|
+
| Tempo | Default | Onde configura | O que acontece |
|
|
207
|
+
| --- | --- | --- | --- |
|
|
208
|
+
| flush automático | `2000` ms | `init({ flushIntervalMs })` | de quanto em quanto o transport esvazia a fila; menor = mais requests, telemetria mais fresca |
|
|
209
|
+
| lote por envelope | `10` itens | `init({ maxBatchSize })` | ao atingir, envia **na hora** sem esperar o intervalo |
|
|
210
|
+
| teto da fila | `200` itens | — (fixo) | fila cheia descarta o item **mais antigo**, com aviso no console |
|
|
211
|
+
| `flush(timeoutMs)` | `5000` ms | argumento | quanto espera os envios em voo antes de devolver `false` |
|
|
212
|
+
| `close(timeoutMs)` | `5000` ms | argumento | idem, no flush final (veja a nota 1 abaixo) |
|
|
213
|
+
| ladder de retry | `1s, 4s, 16s` | — (fixo) | 3 tentativas por envelope; depois ele é descartado. 4xx (exceto 429) não tem retry |
|
|
214
|
+
| heartbeat | `30000` ms | `init({ heartbeat: { intervalMs } })` | bate **imediatamente** no `init()` e depois a cada intervalo; o valor vai no payload e define quanto silêncio o servidor tolera antes de marcar offline |
|
|
215
|
+
|
|
216
|
+
### Manager — polling e runs
|
|
217
|
+
|
|
218
|
+
| Tempo | Default | Onde configura | O que acontece |
|
|
219
|
+
| --- | --- | --- | --- |
|
|
220
|
+
| poll sem trabalho | `5000` ms (mín. `1000`) | `manager: { pollIntervalMs }` | é só o **teto da espera quando não há nada**: com trabalho na fila o próximo poll é imediato ([drain mode](./concepts.md#drain-mode)) |
|
|
221
|
+
| flush de logs da run | `2000` ms | `manager: { logFlushIntervalMs }` | ou na hora, ao acumular 20 linhas |
|
|
222
|
+
| heartbeat de cancelamento | `5000` ms (clamp `1000`..`15000`) | `manager: { cancelCheckIntervalMs }` | detecta cancelamento feito no app **e** é o sinal de vida da run (veja a nota 2) |
|
|
223
|
+
| timeout por run | sem timeout | `manager: { taskTimeoutMs }` | no estouro dispara `ctx.signal`, libera o slot de concorrência e reporta `TaskTimeout` — **não mata** o handler |
|
|
224
|
+
| `stop(timeoutMs)` | `30000` ms | argumento | espera as runs ativas; no estouro elas são reportadas como `AgentTerminated` |
|
|
225
|
+
| retry do poll | `1s, 4s, 16s` | — (fixo) | erros de rede/5xx |
|
|
226
|
+
| retry com chave rejeitada (401) | `30000` ms | — (fixo) | segue tentando devagar, com log throttled |
|
|
227
|
+
| PATCH do caminho de saída | `~2500` ms | — (fixo) | melhor esforço, sem retry, ao morrer com run ativa |
|
|
228
|
+
| sweep do servidor | `~60000` ms | — (servidor) | run `running` sem reporte por esse tempo vira `failed`/`AgentTerminated`, sem re-entrega |
|
|
229
|
+
|
|
230
|
+
**Nota 1 — `close(timeoutMs)` gasta o tempo duas vezes.** Ele espera as runs do Manager (`timeoutMs`) e **depois** faz o flush final (`timeoutMs`), em sequência. Pior caso ≈ `2 × timeoutMs`; `close()` sem argumento pode levar até ~35s (30s aguardando runs + 5s de flush). Se o seu SIGTERM tem prazo curto (Kubernetes, systemd), dimensione por aí.
|
|
231
|
+
|
|
232
|
+
**Nota 2 — o teto de 15s do `cancelCheckIntervalMs` existe por causa do sweep de 60s.** Esse heartbeat é o que mantém o `last_report_at` da run atualizado; o clamp garante que o intervalo nunca chegue perto do prazo em que o servidor declara a run morta.
|