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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Next
|
|
2
2
|
|
|
3
|
+
# 4.3.0 - 2024-11-25
|
|
4
|
+
|
|
5
|
+
1. Add Sentry v8 support to the Sentry integration
|
|
6
|
+
|
|
7
|
+
# 4.2.3 - 2024-11-21
|
|
8
|
+
|
|
9
|
+
1. fix: identify method allows passing a $set_once object
|
|
10
|
+
|
|
3
11
|
# 4.2.2 - 2024-11-18
|
|
4
12
|
|
|
5
13
|
1. fix: Shutdown will now respect the timeout and forcefully return rather than returning after the next fetch.
|
package/lib/index.cjs.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var rusha = require('rusha');
|
|
6
6
|
|
|
7
|
-
var version = "4.
|
|
7
|
+
var version = "4.3.0";
|
|
8
8
|
|
|
9
9
|
var PostHogPersistedProperty;
|
|
10
10
|
(function (PostHogPersistedProperty) {
|
|
@@ -1064,7 +1064,7 @@ class PostHogCoreStateless {
|
|
|
1064
1064
|
identifyStateless(distinctId, properties, options) {
|
|
1065
1065
|
this.wrap(() => {
|
|
1066
1066
|
// The properties passed to identifyStateless are event properties.
|
|
1067
|
-
// To add person properties, pass in all person properties to the `$set`
|
|
1067
|
+
// To add person properties, pass in all person properties to the `$set` and `$set_once` keys.
|
|
1068
1068
|
const payload = {
|
|
1069
1069
|
...this.buildPayload({
|
|
1070
1070
|
distinct_id: distinctId,
|
|
@@ -2163,9 +2163,14 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2163
2163
|
disableGeoip
|
|
2164
2164
|
}) {
|
|
2165
2165
|
// Catch properties passed as $set and move them to the top level
|
|
2166
|
-
|
|
2166
|
+
// promote $set and $set_once to top level
|
|
2167
|
+
const userPropsOnce = properties?.$set_once;
|
|
2168
|
+
delete properties?.$set_once;
|
|
2169
|
+
// if no $set is provided we assume all properties are $set
|
|
2170
|
+
const userProps = properties?.$set || properties;
|
|
2167
2171
|
super.identifyStateless(distinctId, {
|
|
2168
|
-
$set:
|
|
2172
|
+
$set: userProps,
|
|
2173
|
+
$set_once: userPropsOnce
|
|
2169
2174
|
}, {
|
|
2170
2175
|
disableGeoip
|
|
2171
2176
|
});
|
|
@@ -2360,6 +2365,9 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2360
2365
|
}
|
|
2361
2366
|
}
|
|
2362
2367
|
|
|
2368
|
+
/**
|
|
2369
|
+
* @file Adapted from [posthog-js](https://github.com/PostHog/posthog-js/blob/8157df935a4d0e71d2fefef7127aa85ee51c82d1/src/extensions/sentry-integration.ts) with modifications for the Node SDK.
|
|
2370
|
+
*/
|
|
2363
2371
|
/**
|
|
2364
2372
|
* Integrate Sentry with PostHog. This will add a direct link to the person in Sentry, and an $exception event in PostHog.
|
|
2365
2373
|
*
|
|
@@ -2378,59 +2386,96 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2378
2386
|
* @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry
|
|
2379
2387
|
* @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry
|
|
2380
2388
|
* @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)
|
|
2389
|
+
* @param {SeverityLevel[] | '*'} [severityAllowList] Optional: send events matching the provided levels. Use '*' to send all events (default: ['error'])
|
|
2381
2390
|
*/
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
if (userId === undefined) {
|
|
2403
|
-
// 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.
|
|
2404
|
-
return event;
|
|
2405
|
-
}
|
|
2406
|
-
event.tags['PostHog Person URL'] = new URL(`/person/${userId}`, this.posthogHost).toString();
|
|
2407
|
-
const properties = {
|
|
2408
|
-
// PostHog Exception Properties
|
|
2409
|
-
$exception_message: event.exception.values[0]?.value,
|
|
2410
|
-
$exception_type: event.exception.values[0]?.type,
|
|
2411
|
-
$exception_personURL: event.tags['PostHog Person URL'],
|
|
2412
|
-
// Sentry Exception Properties
|
|
2413
|
-
$sentry_event_id: event.event_id,
|
|
2414
|
-
$sentry_exception: event.exception,
|
|
2415
|
-
$sentry_exception_message: event.exception.values[0]?.value,
|
|
2416
|
-
$sentry_exception_type: event.exception.values[0]?.type,
|
|
2417
|
-
$sentry_tags: event.tags
|
|
2418
|
-
};
|
|
2419
|
-
const projectId = sentry.getClient()?.getDsn()?.projectId;
|
|
2420
|
-
if (this.organization !== undefined && projectId !== undefined && event.event_id !== undefined) {
|
|
2421
|
-
properties.$sentry_url = `${this.prefix ?? 'https://sentry.io/organizations'}/${this.organization}/issues/?project=${projectId}&query=${event.event_id}`;
|
|
2422
|
-
}
|
|
2423
|
-
this.posthog.capture({
|
|
2424
|
-
event: '$exception',
|
|
2425
|
-
distinctId: userId,
|
|
2426
|
-
properties
|
|
2427
|
-
});
|
|
2391
|
+
const severityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'];
|
|
2392
|
+
const NAME = 'posthog-node';
|
|
2393
|
+
function createEventProcessor(_posthog, {
|
|
2394
|
+
organization,
|
|
2395
|
+
projectId,
|
|
2396
|
+
prefix,
|
|
2397
|
+
severityAllowList = ['error']
|
|
2398
|
+
} = {}) {
|
|
2399
|
+
return event => {
|
|
2400
|
+
const shouldProcessLevel = severityAllowList === '*' || severityAllowList.includes(event.level);
|
|
2401
|
+
if (!shouldProcessLevel) {
|
|
2402
|
+
return event;
|
|
2403
|
+
}
|
|
2404
|
+
if (!event.tags) {
|
|
2405
|
+
event.tags = {};
|
|
2406
|
+
}
|
|
2407
|
+
// Get the PostHog user ID from a specific tag, which users can set on their Sentry scope as they need.
|
|
2408
|
+
const userId = event.tags[PostHogSentryIntegration.POSTHOG_ID_TAG];
|
|
2409
|
+
if (userId === undefined) {
|
|
2410
|
+
// 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.
|
|
2428
2411
|
return event;
|
|
2412
|
+
}
|
|
2413
|
+
const uiHost = _posthog.options.host ?? 'https://us.i.posthog.com';
|
|
2414
|
+
const personUrl = new URL(`/project/${_posthog.apiKey}/person/${userId}`, uiHost).toString();
|
|
2415
|
+
event.tags['PostHog Person URL'] = personUrl;
|
|
2416
|
+
const exceptions = event.exception?.values || [];
|
|
2417
|
+
exceptions.map(exception => {
|
|
2418
|
+
if (exception.stacktrace) {
|
|
2419
|
+
exception.stacktrace.type = 'raw';
|
|
2420
|
+
}
|
|
2421
|
+
});
|
|
2422
|
+
const properties = {
|
|
2423
|
+
// PostHog Exception Properties,
|
|
2424
|
+
$exception_message: exceptions[0]?.value || event.message,
|
|
2425
|
+
$exception_type: exceptions[0]?.type,
|
|
2426
|
+
$exception_personURL: personUrl,
|
|
2427
|
+
$exception_level: event.level,
|
|
2428
|
+
$exception_list: exceptions,
|
|
2429
|
+
// Sentry Exception Properties
|
|
2430
|
+
$sentry_event_id: event.event_id,
|
|
2431
|
+
$sentry_exception: event.exception,
|
|
2432
|
+
$sentry_exception_message: exceptions[0]?.value || event.message,
|
|
2433
|
+
$sentry_exception_type: exceptions[0]?.type,
|
|
2434
|
+
$sentry_tags: event.tags
|
|
2435
|
+
};
|
|
2436
|
+
if (organization && projectId) {
|
|
2437
|
+
properties['$sentry_url'] = (prefix || 'https://sentry.io/organizations/') + organization + '/issues/?project=' + projectId + '&query=' + event.event_id;
|
|
2438
|
+
}
|
|
2439
|
+
_posthog.capture({
|
|
2440
|
+
event: '$exception',
|
|
2441
|
+
distinctId: userId,
|
|
2442
|
+
properties
|
|
2429
2443
|
});
|
|
2444
|
+
return event;
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2447
|
+
// V8 integration - function based
|
|
2448
|
+
function sentryIntegration(_posthog, options) {
|
|
2449
|
+
const processor = createEventProcessor(_posthog, options);
|
|
2450
|
+
return {
|
|
2451
|
+
name: NAME,
|
|
2452
|
+
processEvent(event) {
|
|
2453
|
+
return processor(event);
|
|
2454
|
+
}
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
// V7 integration - class based
|
|
2458
|
+
class PostHogSentryIntegration {
|
|
2459
|
+
constructor(_posthog, organization, prefix, severityAllowList) {
|
|
2460
|
+
this.name = NAME;
|
|
2461
|
+
// setupOnce gets called by Sentry when it intializes the plugin
|
|
2462
|
+
this.name = NAME;
|
|
2463
|
+
this.setupOnce = function (addGlobalEventProcessor, getCurrentHub) {
|
|
2464
|
+
const projectId = getCurrentHub()?.getClient()?.getDsn()?.projectId;
|
|
2465
|
+
addGlobalEventProcessor(createEventProcessor(_posthog, {
|
|
2466
|
+
organization,
|
|
2467
|
+
projectId,
|
|
2468
|
+
prefix,
|
|
2469
|
+
severityAllowList
|
|
2470
|
+
}));
|
|
2471
|
+
};
|
|
2430
2472
|
}
|
|
2431
2473
|
}
|
|
2432
2474
|
PostHogSentryIntegration.POSTHOG_ID_TAG = 'posthog_distinct_id';
|
|
2433
2475
|
|
|
2434
2476
|
exports.PostHog = PostHog;
|
|
2435
2477
|
exports.PostHogSentryIntegration = PostHogSentryIntegration;
|
|
2478
|
+
exports.createEventProcessor = createEventProcessor;
|
|
2479
|
+
exports.sentryIntegration = sentryIntegration;
|
|
2480
|
+
exports.severityLevels = severityLevels;
|
|
2436
2481
|
//# sourceMappingURL=index.cjs.js.map
|