@monocle-app/agent 1.0.0-beta.0 → 1.0.0-beta.1
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 +131 -1
- package/dist/configure.d.mts +7 -0
- package/dist/configure.mjs +61 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/init.mjs +3 -3
- package/dist/stubs/config.stub +13 -0
- package/dist/stubs/main.mjs +8 -0
- package/dist/stubs/main.ts +4 -0
- package/dist/stubs/otel.stub +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,133 @@
|
|
|
1
1
|
# @monocle-app/agent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Monocle agent for AdonisJS - sends telemetry to Monocle cloud.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @monocle-app/agent
|
|
9
|
+
# or
|
|
10
|
+
yarn add @monocle-app/agent
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @monocle-app/agent
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
Run the configure command to set up the agent automatically:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
node ace configure @monocle-app/agent
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This will:
|
|
24
|
+
|
|
25
|
+
1. Create `config/monocle.ts` configuration file
|
|
26
|
+
2. Create `otel.ts` initialization file at project root
|
|
27
|
+
3. Add the otel.ts import as the first import in `bin/server.ts`
|
|
28
|
+
4. Register the Monocle provider in `adonisrc.ts`
|
|
29
|
+
5. Register the Monocle middleware as the first router middleware
|
|
30
|
+
6. Add required environment variables to `.env` and `start/env.ts`
|
|
31
|
+
|
|
32
|
+
After configuration, add your API key to `.env`:
|
|
33
|
+
|
|
34
|
+
```env
|
|
35
|
+
MONOCLE_API_KEY=mk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## User Identification
|
|
39
|
+
|
|
40
|
+
To associate telemetry data with authenticated users, add `Monocle.setUser()` in your authentication middleware:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import type { NextFn } from '@adonisjs/core/types/http'
|
|
44
|
+
import type { HttpContext } from '@adonisjs/core/http'
|
|
45
|
+
import { Monocle } from '@monocle-app/agent'
|
|
46
|
+
|
|
47
|
+
export default class SilentAuthMiddleware {
|
|
48
|
+
async handle(ctx: HttpContext, next: NextFn) {
|
|
49
|
+
await ctx.auth.check()
|
|
50
|
+
|
|
51
|
+
if (ctx.auth.user) Monocle.setUser(ctx.auth.user)
|
|
52
|
+
|
|
53
|
+
return next()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Exception Tracking
|
|
59
|
+
|
|
60
|
+
Exceptions are automatically recorded in spans when thrown during a request. The agent hooks into AdonisJS's `ExceptionHandler.report()` method to capture exceptions with their stack traces.
|
|
61
|
+
|
|
62
|
+
If you want to manually capture exceptions in custom code:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { Monocle } from '@monocle-app/agent'
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
// your code
|
|
69
|
+
} catch (error) {
|
|
70
|
+
Monocle.captureException(error, {
|
|
71
|
+
user: { id: '123', email: 'user@example.com' },
|
|
72
|
+
tags: { component: 'payment' },
|
|
73
|
+
extra: { orderId: 456 },
|
|
74
|
+
})
|
|
75
|
+
throw error
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Configuration Options
|
|
80
|
+
|
|
81
|
+
The `config/monocle.ts` file supports the following options:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { defineConfig } from '@monocle-app/agent'
|
|
85
|
+
import env from '#start/env'
|
|
86
|
+
|
|
87
|
+
export default defineConfig({
|
|
88
|
+
// Required: Your Monocle API key
|
|
89
|
+
apiKey: env.get('MONOCLE_API_KEY'),
|
|
90
|
+
|
|
91
|
+
// Optional: Custom ingestion endpoint (for development)
|
|
92
|
+
// endpoint: 'http://localhost:4318',
|
|
93
|
+
|
|
94
|
+
// Service identification
|
|
95
|
+
serviceName: env.get('APP_NAME'),
|
|
96
|
+
serviceVersion: env.get('APP_VERSION'),
|
|
97
|
+
environment: env.get('APP_ENV'),
|
|
98
|
+
|
|
99
|
+
// Host metrics (CPU, Memory, Network, etc.)
|
|
100
|
+
// Set to false to disable
|
|
101
|
+
hostMetrics: {
|
|
102
|
+
enabled: true,
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// CLI command tracing
|
|
106
|
+
cli: {
|
|
107
|
+
enabled: false,
|
|
108
|
+
exclude: ['make:*', 'generate:*', 'queue:work', 'queue:listen'],
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Trace batching configuration
|
|
112
|
+
batch: {
|
|
113
|
+
maxExportBatchSize: 512,
|
|
114
|
+
scheduledDelayMillis: 5000,
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Enable gzip compression (default: true)
|
|
118
|
+
compression: true,
|
|
119
|
+
})
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Environment Variables
|
|
123
|
+
|
|
124
|
+
| Variable | Description | Required |
|
|
125
|
+
|----------|-------------|----------|
|
|
126
|
+
| `MONOCLE_API_KEY` | Your Monocle API key | Yes |
|
|
127
|
+
| `APP_NAME` | Service name for identification | Yes |
|
|
128
|
+
| `APP_VERSION` | Service version (e.g., git sha, semver) | Yes |
|
|
129
|
+
| `APP_ENV` | Environment: `development`, `staging`, or `production` | Yes |
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
ISC
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { stubsRoot } from "./stubs/main.mjs";
|
|
2
|
+
|
|
3
|
+
//#region configure.ts
|
|
4
|
+
async function configure(command) {
|
|
5
|
+
const codemods = await command.createCodemods();
|
|
6
|
+
/**
|
|
7
|
+
* Publish config/monocle.ts
|
|
8
|
+
*/
|
|
9
|
+
await codemods.makeUsingStub(stubsRoot, "config.stub", {});
|
|
10
|
+
/**
|
|
11
|
+
* Publish otel.ts at project root
|
|
12
|
+
*/
|
|
13
|
+
await codemods.makeUsingStub(stubsRoot, "otel.stub", {});
|
|
14
|
+
const serverFile = (await codemods.getTsMorphProject())?.getSourceFile(command.app.makePath("bin/server.ts"));
|
|
15
|
+
if (serverFile) {
|
|
16
|
+
const insertIndex = serverFile.getImportDeclarations()[0]?.getChildIndex() ?? 0;
|
|
17
|
+
serverFile.insertStatements(insertIndex, [
|
|
18
|
+
"/**",
|
|
19
|
+
" * OpenTelemetry initialization - MUST be the first import",
|
|
20
|
+
" * @see https://opentelemetry.io/docs/languages/js/getting-started/nodejs/",
|
|
21
|
+
" */",
|
|
22
|
+
`import '../otel.js'`,
|
|
23
|
+
""
|
|
24
|
+
]);
|
|
25
|
+
await serverFile.save();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Register the provider in adonisrc.ts
|
|
29
|
+
*/
|
|
30
|
+
await codemods.updateRcFile((rcFile) => {
|
|
31
|
+
rcFile.addProvider("@monocle-app/agent/monocle_provider");
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Register the middleware as FIRST router middleware
|
|
35
|
+
*/
|
|
36
|
+
await codemods.registerMiddleware("router", [{
|
|
37
|
+
path: "@monocle-app/agent/monocle_middleware",
|
|
38
|
+
position: "before"
|
|
39
|
+
}]);
|
|
40
|
+
/**
|
|
41
|
+
* Define environment variables in .env
|
|
42
|
+
*/
|
|
43
|
+
await codemods.defineEnvVariables({
|
|
44
|
+
APP_NAME: command.app.appName,
|
|
45
|
+
APP_VERSION: "0.0.1",
|
|
46
|
+
APP_ENV: "development",
|
|
47
|
+
MONOCLE_API_KEY: ""
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Define environment validations in start/env.ts
|
|
51
|
+
*/
|
|
52
|
+
await codemods.defineEnvValidations({ variables: {
|
|
53
|
+
APP_NAME: "Env.schema.string()",
|
|
54
|
+
APP_VERSION: "Env.schema.string()",
|
|
55
|
+
APP_ENV: `Env.schema.enum(['development', 'staging', 'production'] as const)`,
|
|
56
|
+
MONOCLE_API_KEY: "Env.schema.string()"
|
|
57
|
+
} });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { configure };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BatchConfig, CliTracingConfig, HostMetricsConfig, MonocleConfig } from "./src/types.mjs";
|
|
2
2
|
import { defineConfig } from "./src/define_config.mjs";
|
|
3
3
|
import { Monocle } from "./src/monocle.mjs";
|
|
4
|
-
|
|
4
|
+
import { configure } from "./configure.mjs";
|
|
5
|
+
export { type BatchConfig, type CliTracingConfig, type HostMetricsConfig, Monocle, type MonocleConfig, configure, defineConfig };
|
package/dist/index.mjs
CHANGED
package/dist/init.mjs
CHANGED
|
@@ -52,10 +52,10 @@ async function createSpanProcessor(config) {
|
|
|
52
52
|
maxQueueSize: batchConfig.maxQueueSize
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
-
async function init(dirname) {
|
|
55
|
+
async function init(dirname$1) {
|
|
56
56
|
const waitForAllMessagesAcknowledged = setupHooks();
|
|
57
57
|
const { OtelManager } = await import("@adonisjs/otel/manager");
|
|
58
|
-
const config = await loadConfig(join(dirname, "config/monocle.js"));
|
|
58
|
+
const config = await loadConfig(join(dirname$1, "config/monocle.js"));
|
|
59
59
|
if (!config) return;
|
|
60
60
|
if (!OtelManager.isEnabled(config)) return;
|
|
61
61
|
const metricReader = await createMetricReader(config);
|
|
@@ -102,7 +102,7 @@ async function init(dirname) {
|
|
|
102
102
|
const cliConfig = config.cli;
|
|
103
103
|
if (cliConfig !== false && cliConfig?.enabled) {
|
|
104
104
|
const { instrumentCliCommands } = await import("./src/cli_instrumentation.mjs");
|
|
105
|
-
await instrumentCliCommands(cliConfig, dirname);
|
|
105
|
+
await instrumentCliCommands(cliConfig, dirname$1);
|
|
106
106
|
}
|
|
107
107
|
await waitForAllMessagesAcknowledged();
|
|
108
108
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.configPath('monocle.ts') })
|
|
3
|
+
}}}
|
|
4
|
+
import { defineConfig } from '@monocle-app/agent'
|
|
5
|
+
import env from '#start/env'
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
apiKey: env.get('MONOCLE_API_KEY'),
|
|
9
|
+
|
|
10
|
+
serviceName: env.get('APP_NAME'),
|
|
11
|
+
serviceVersion: env.get('APP_VERSION'),
|
|
12
|
+
environment: env.get('APP_ENV'),
|
|
13
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.makePath('otel.ts') })
|
|
3
|
+
}}}
|
|
4
|
+
/**
|
|
5
|
+
* Monocle agent initialization file.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: This file must be imported FIRST in bin/server.ts
|
|
8
|
+
* for auto-instrumentation to work correctly.
|
|
9
|
+
*/
|
|
10
|
+
import { init } from '@monocle-app/agent/init'
|
|
11
|
+
|
|
12
|
+
await init(import.meta.dirname)
|