posthog-node 4.2.2 → 4.3.0
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/CHANGELOG.md +8 -0
- package/lib/index.cjs.js +95 -50
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +20 -28
- package/lib/index.esm.js +93 -51
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +1 -1
- package/lib/posthog-node/src/extensions/sentry-integration.d.ts +26 -14
- package/package.json +1 -1
- package/src/extensions/sentry-integration.ts +142 -76
- package/src/posthog-node.ts +9 -2
- package/test/extensions/sentry-integration.spec.ts +13 -3
- package/test/posthog-node.spec.ts +29 -3
package/lib/index.d.ts
CHANGED
|
@@ -132,7 +132,7 @@ declare class SimpleEventEmitter {
|
|
|
132
132
|
declare abstract class PostHogCoreStateless {
|
|
133
133
|
readonly apiKey: string;
|
|
134
134
|
readonly host: string;
|
|
135
|
-
|
|
135
|
+
readonly flushAt: number;
|
|
136
136
|
private maxBatchSize;
|
|
137
137
|
private maxQueueSize;
|
|
138
138
|
private flushInterval;
|
|
@@ -435,40 +435,32 @@ declare class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
|
|
|
435
435
|
* @file Adapted from [posthog-js](https://github.com/PostHog/posthog-js/blob/8157df935a4d0e71d2fefef7127aa85ee51c82d1/src/extensions/sentry-integration.ts) with modifications for the Node SDK.
|
|
436
436
|
*/
|
|
437
437
|
|
|
438
|
+
declare const severityLevels: readonly ["fatal", "error", "warning", "log", "info", "debug"];
|
|
439
|
+
declare type SeverityLevel = (typeof severityLevels)[number];
|
|
440
|
+
type _SentryEvent = any;
|
|
438
441
|
type _SentryEventProcessor = any;
|
|
439
442
|
type _SentryHub = any;
|
|
440
443
|
interface _SentryIntegration {
|
|
444
|
+
name: string;
|
|
445
|
+
processEvent(event: _SentryEvent): _SentryEvent;
|
|
446
|
+
}
|
|
447
|
+
interface _SentryIntegrationClass {
|
|
441
448
|
name: string;
|
|
442
449
|
setupOnce(addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub): void;
|
|
443
450
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
*
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
* ]
|
|
454
|
-
* })
|
|
455
|
-
*
|
|
456
|
-
* Sentry.setTag(PostHogSentryIntegration.POSTHOG_ID_TAG, 'some distinct id');
|
|
457
|
-
*
|
|
458
|
-
* @param {Object} [posthog] The posthog object
|
|
459
|
-
* @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry
|
|
460
|
-
* @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry
|
|
461
|
-
* @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)
|
|
462
|
-
*/
|
|
463
|
-
declare class PostHogSentryIntegration implements _SentryIntegration {
|
|
464
|
-
private readonly posthog;
|
|
465
|
-
private readonly posthogHost?;
|
|
466
|
-
private readonly organization?;
|
|
467
|
-
private readonly prefix?;
|
|
451
|
+
type SentryIntegrationOptions = {
|
|
452
|
+
organization?: string;
|
|
453
|
+
projectId?: number;
|
|
454
|
+
prefix?: string;
|
|
455
|
+
severityAllowList?: SeverityLevel[] | '*';
|
|
456
|
+
};
|
|
457
|
+
declare function createEventProcessor(_posthog: PostHog, { organization, projectId, prefix, severityAllowList }?: SentryIntegrationOptions): (event: _SentryEvent) => _SentryEvent;
|
|
458
|
+
declare function sentryIntegration(_posthog: PostHog, options?: SentryIntegrationOptions): _SentryIntegration;
|
|
459
|
+
declare class PostHogSentryIntegration implements _SentryIntegrationClass {
|
|
468
460
|
readonly name = "posthog-node";
|
|
469
461
|
static readonly POSTHOG_ID_TAG = "posthog_distinct_id";
|
|
470
|
-
|
|
471
|
-
|
|
462
|
+
setupOnce: (addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub) => void;
|
|
463
|
+
constructor(_posthog: PostHog, organization?: string, prefix?: string, severityAllowList?: SeverityLevel[] | '*');
|
|
472
464
|
}
|
|
473
465
|
|
|
474
|
-
export { PostHog, PostHogOptions, PostHogSentryIntegration };
|
|
466
|
+
export { PostHog, PostHogOptions, PostHogSentryIntegration, SentryIntegrationOptions, SeverityLevel, createEventProcessor, sentryIntegration, severityLevels };
|
package/lib/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'rusha';
|
|
2
2
|
|
|
3
|
-
var version = "4.
|
|
3
|
+
var version = "4.3.0";
|
|
4
4
|
|
|
5
5
|
var PostHogPersistedProperty;
|
|
6
6
|
(function (PostHogPersistedProperty) {
|
|
@@ -1060,7 +1060,7 @@ class PostHogCoreStateless {
|
|
|
1060
1060
|
identifyStateless(distinctId, properties, options) {
|
|
1061
1061
|
this.wrap(() => {
|
|
1062
1062
|
// The properties passed to identifyStateless are event properties.
|
|
1063
|
-
// To add person properties, pass in all person properties to the `$set`
|
|
1063
|
+
// To add person properties, pass in all person properties to the `$set` and `$set_once` keys.
|
|
1064
1064
|
const payload = {
|
|
1065
1065
|
...this.buildPayload({
|
|
1066
1066
|
distinct_id: distinctId,
|
|
@@ -2159,9 +2159,14 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2159
2159
|
disableGeoip
|
|
2160
2160
|
}) {
|
|
2161
2161
|
// Catch properties passed as $set and move them to the top level
|
|
2162
|
-
|
|
2162
|
+
// promote $set and $set_once to top level
|
|
2163
|
+
const userPropsOnce = properties?.$set_once;
|
|
2164
|
+
delete properties?.$set_once;
|
|
2165
|
+
// if no $set is provided we assume all properties are $set
|
|
2166
|
+
const userProps = properties?.$set || properties;
|
|
2163
2167
|
super.identifyStateless(distinctId, {
|
|
2164
|
-
$set:
|
|
2168
|
+
$set: userProps,
|
|
2169
|
+
$set_once: userPropsOnce
|
|
2165
2170
|
}, {
|
|
2166
2171
|
disableGeoip
|
|
2167
2172
|
});
|
|
@@ -2356,6 +2361,9 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2356
2361
|
}
|
|
2357
2362
|
}
|
|
2358
2363
|
|
|
2364
|
+
/**
|
|
2365
|
+
* @file Adapted from [posthog-js](https://github.com/PostHog/posthog-js/blob/8157df935a4d0e71d2fefef7127aa85ee51c82d1/src/extensions/sentry-integration.ts) with modifications for the Node SDK.
|
|
2366
|
+
*/
|
|
2359
2367
|
/**
|
|
2360
2368
|
* Integrate Sentry with PostHog. This will add a direct link to the person in Sentry, and an $exception event in PostHog.
|
|
2361
2369
|
*
|
|
@@ -2374,58 +2382,92 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2374
2382
|
* @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry
|
|
2375
2383
|
* @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry
|
|
2376
2384
|
* @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)
|
|
2385
|
+
* @param {SeverityLevel[] | '*'} [severityAllowList] Optional: send events matching the provided levels. Use '*' to send all events (default: ['error'])
|
|
2377
2386
|
*/
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
if (userId === undefined) {
|
|
2399
|
-
// If we can't find a user ID, don't bother linking the event. We won't be able to send anything meaningful to PostHog without it.
|
|
2400
|
-
return event;
|
|
2401
|
-
}
|
|
2402
|
-
event.tags['PostHog Person URL'] = new URL(`/person/${userId}`, this.posthogHost).toString();
|
|
2403
|
-
const properties = {
|
|
2404
|
-
// PostHog Exception Properties
|
|
2405
|
-
$exception_message: event.exception.values[0]?.value,
|
|
2406
|
-
$exception_type: event.exception.values[0]?.type,
|
|
2407
|
-
$exception_personURL: event.tags['PostHog Person URL'],
|
|
2408
|
-
// Sentry Exception Properties
|
|
2409
|
-
$sentry_event_id: event.event_id,
|
|
2410
|
-
$sentry_exception: event.exception,
|
|
2411
|
-
$sentry_exception_message: event.exception.values[0]?.value,
|
|
2412
|
-
$sentry_exception_type: event.exception.values[0]?.type,
|
|
2413
|
-
$sentry_tags: event.tags
|
|
2414
|
-
};
|
|
2415
|
-
const projectId = sentry.getClient()?.getDsn()?.projectId;
|
|
2416
|
-
if (this.organization !== undefined && projectId !== undefined && event.event_id !== undefined) {
|
|
2417
|
-
properties.$sentry_url = `${this.prefix ?? 'https://sentry.io/organizations'}/${this.organization}/issues/?project=${projectId}&query=${event.event_id}`;
|
|
2418
|
-
}
|
|
2419
|
-
this.posthog.capture({
|
|
2420
|
-
event: '$exception',
|
|
2421
|
-
distinctId: userId,
|
|
2422
|
-
properties
|
|
2423
|
-
});
|
|
2387
|
+
const severityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'];
|
|
2388
|
+
const NAME = 'posthog-node';
|
|
2389
|
+
function createEventProcessor(_posthog, {
|
|
2390
|
+
organization,
|
|
2391
|
+
projectId,
|
|
2392
|
+
prefix,
|
|
2393
|
+
severityAllowList = ['error']
|
|
2394
|
+
} = {}) {
|
|
2395
|
+
return event => {
|
|
2396
|
+
const shouldProcessLevel = severityAllowList === '*' || severityAllowList.includes(event.level);
|
|
2397
|
+
if (!shouldProcessLevel) {
|
|
2398
|
+
return event;
|
|
2399
|
+
}
|
|
2400
|
+
if (!event.tags) {
|
|
2401
|
+
event.tags = {};
|
|
2402
|
+
}
|
|
2403
|
+
// Get the PostHog user ID from a specific tag, which users can set on their Sentry scope as they need.
|
|
2404
|
+
const userId = event.tags[PostHogSentryIntegration.POSTHOG_ID_TAG];
|
|
2405
|
+
if (userId === undefined) {
|
|
2406
|
+
// If we can't find a user ID, don't bother linking the event. We won't be able to send anything meaningful to PostHog without it.
|
|
2424
2407
|
return event;
|
|
2408
|
+
}
|
|
2409
|
+
const uiHost = _posthog.options.host ?? 'https://us.i.posthog.com';
|
|
2410
|
+
const personUrl = new URL(`/project/${_posthog.apiKey}/person/${userId}`, uiHost).toString();
|
|
2411
|
+
event.tags['PostHog Person URL'] = personUrl;
|
|
2412
|
+
const exceptions = event.exception?.values || [];
|
|
2413
|
+
exceptions.map(exception => {
|
|
2414
|
+
if (exception.stacktrace) {
|
|
2415
|
+
exception.stacktrace.type = 'raw';
|
|
2416
|
+
}
|
|
2417
|
+
});
|
|
2418
|
+
const properties = {
|
|
2419
|
+
// PostHog Exception Properties,
|
|
2420
|
+
$exception_message: exceptions[0]?.value || event.message,
|
|
2421
|
+
$exception_type: exceptions[0]?.type,
|
|
2422
|
+
$exception_personURL: personUrl,
|
|
2423
|
+
$exception_level: event.level,
|
|
2424
|
+
$exception_list: exceptions,
|
|
2425
|
+
// Sentry Exception Properties
|
|
2426
|
+
$sentry_event_id: event.event_id,
|
|
2427
|
+
$sentry_exception: event.exception,
|
|
2428
|
+
$sentry_exception_message: exceptions[0]?.value || event.message,
|
|
2429
|
+
$sentry_exception_type: exceptions[0]?.type,
|
|
2430
|
+
$sentry_tags: event.tags
|
|
2431
|
+
};
|
|
2432
|
+
if (organization && projectId) {
|
|
2433
|
+
properties['$sentry_url'] = (prefix || 'https://sentry.io/organizations/') + organization + '/issues/?project=' + projectId + '&query=' + event.event_id;
|
|
2434
|
+
}
|
|
2435
|
+
_posthog.capture({
|
|
2436
|
+
event: '$exception',
|
|
2437
|
+
distinctId: userId,
|
|
2438
|
+
properties
|
|
2425
2439
|
});
|
|
2440
|
+
return event;
|
|
2441
|
+
};
|
|
2442
|
+
}
|
|
2443
|
+
// V8 integration - function based
|
|
2444
|
+
function sentryIntegration(_posthog, options) {
|
|
2445
|
+
const processor = createEventProcessor(_posthog, options);
|
|
2446
|
+
return {
|
|
2447
|
+
name: NAME,
|
|
2448
|
+
processEvent(event) {
|
|
2449
|
+
return processor(event);
|
|
2450
|
+
}
|
|
2451
|
+
};
|
|
2452
|
+
}
|
|
2453
|
+
// V7 integration - class based
|
|
2454
|
+
class PostHogSentryIntegration {
|
|
2455
|
+
constructor(_posthog, organization, prefix, severityAllowList) {
|
|
2456
|
+
this.name = NAME;
|
|
2457
|
+
// setupOnce gets called by Sentry when it intializes the plugin
|
|
2458
|
+
this.name = NAME;
|
|
2459
|
+
this.setupOnce = function (addGlobalEventProcessor, getCurrentHub) {
|
|
2460
|
+
const projectId = getCurrentHub()?.getClient()?.getDsn()?.projectId;
|
|
2461
|
+
addGlobalEventProcessor(createEventProcessor(_posthog, {
|
|
2462
|
+
organization,
|
|
2463
|
+
projectId,
|
|
2464
|
+
prefix,
|
|
2465
|
+
severityAllowList
|
|
2466
|
+
}));
|
|
2467
|
+
};
|
|
2426
2468
|
}
|
|
2427
2469
|
}
|
|
2428
2470
|
PostHogSentryIntegration.POSTHOG_ID_TAG = 'posthog_distinct_id';
|
|
2429
2471
|
|
|
2430
|
-
export { PostHog, PostHogSentryIntegration };
|
|
2472
|
+
export { PostHog, PostHogSentryIntegration, createEventProcessor, sentryIntegration, severityLevels };
|
|
2431
2473
|
//# sourceMappingURL=index.esm.js.map
|