feat: update logEvent to pass eventType and replace segment calls wit… (#7209)

* feat: update logEvent to pass eventType and replace segment calls with logEvent

* feat: update logEvent to handle rate limiting

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
Yunus M 2025-03-07 15:42:51 +05:30 committed by GitHub
parent 42f7511e06
commit d362f5bce3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 52 additions and 105 deletions

View File

@ -1,13 +1,13 @@
import { ConfigProvider } from 'antd';
import getLocalStorageApi from 'api/browser/localstorage/get';
import setLocalStorageApi from 'api/browser/localstorage/set';
import logEvent from 'api/common/logEvent';
import NotFound from 'components/NotFound';
import Spinner from 'components/Spinner';
import { FeatureKeys } from 'constants/features';
import { LOCALSTORAGE } from 'constants/localStorage';
import ROUTES from 'constants/routes';
import AppLayout from 'container/AppLayout';
import useAnalytics from 'hooks/analytics/useAnalytics';
import { KeyboardHotkeysProvider } from 'hooks/hotkeys/useKeyboardHotkeys';
import { useThemeConfig } from 'hooks/useDarkMode';
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
@ -15,7 +15,6 @@ import { LICENSE_PLAN_KEY } from 'hooks/useLicense';
import { NotificationProvider } from 'hooks/useNotifications';
import { ResourceProvider } from 'hooks/useResourceAttribute';
import history from 'lib/history';
import { identity, pickBy } from 'lodash-es';
import posthog from 'posthog-js';
import AlertRuleProvider from 'providers/Alert';
import { useAppContext } from 'providers/App/App';
@ -51,8 +50,6 @@ function App(): JSX.Element {
} = useAppContext();
const [routes, setRoutes] = useState<AppRoutes[]>(defaultRoutes);
const { trackPageView } = useAnalytics();
const { hostname, pathname } = window.location;
const {
@ -69,18 +66,21 @@ function App(): JSX.Element {
const { name, email, role } = user;
const domain = extractDomain(email);
const hostNameParts = hostname.split('.');
const identifyPayload = {
email,
name,
company_name: orgName,
role,
tenant_id: hostNameParts[0],
data_region: hostNameParts[1],
tenant_url: hostname,
company_domain: domain,
source: 'signoz-ui',
role,
};
const sanitizedIdentifyPayload = pickBy(identifyPayload, identity);
const domain = extractDomain(email);
const hostNameParts = hostname.split('.');
const groupTraits = {
name: orgName,
tenant_id: hostNameParts[0],
@ -90,8 +90,13 @@ function App(): JSX.Element {
source: 'signoz-ui',
};
window.analytics.identify(email, sanitizedIdentifyPayload);
window.analytics.group(domain, groupTraits);
if (email) {
logEvent('Email Identified', identifyPayload, 'identify');
}
if (domain) {
logEvent('Domain Identified', groupTraits, 'group');
}
posthog?.identify(email, {
email,
@ -192,9 +197,7 @@ function App(): JSX.Element {
hide_default_launcher: false,
});
}
trackPageView(pathname);
}, [pathname, trackPageView]);
}, [pathname]);
useEffect(() => {
// feature flag shouldn't be loading and featureFlags or fetchError any one of this should be true indicating that req is complete

View File

@ -7,11 +7,15 @@ import { EventSuccessPayloadProps } from 'types/api/events/types';
const logEvent = async (
eventName: string,
attributes: Record<string, unknown>,
eventType?: 'track' | 'group' | 'identify',
rateLimited?: boolean,
): Promise<SuccessResponse<EventSuccessPayloadProps> | ErrorResponse> => {
try {
const response = await axios.post('/event', {
eventName,
attributes,
eventType: eventType || 'track',
rateLimited: rateLimited || false, // TODO: Update this once we have a proper way to handle rate limiting
});
return {

View File

@ -392,11 +392,16 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
LOCALSTORAGE.DONT_SHOW_SLOW_API_WARNING,
);
logEvent(`Slow API Warning`, {
duration: `${data.duration}ms`,
url: data.url,
threshold: data.threshold,
});
logEvent(
`Slow API Warning`,
{
durationMs: data.duration,
url: data.url,
thresholdMs: data.threshold,
},
'track',
true, // rate limited - controlled by Backend
);
const isDontShowSlowApiWarning = dontShowSlowApiWarning === 'true';

View File

@ -19,10 +19,6 @@ jest.mock('hooks/useNotifications', () => ({
})),
}));
window.analytics = {
track: jest.fn(),
};
describe('Onboarding invite team member flow', () => {
it('initial render and get started page', async () => {
const { findByText } = render(

View File

@ -1,40 +0,0 @@
import { useAppContext } from 'providers/App/App';
import { useCallback } from 'react';
import { extractDomain } from 'utils/app';
const useAnalytics = (): any => {
const { user } = useAppContext();
// Segment Page View - analytics.page([category], [name], [properties], [options], [callback]);
const trackPageView = useCallback(
(pageName: string): void => {
if (user && user.email) {
window.analytics.page(null, pageName, {
userId: user.email,
});
}
},
[user],
);
const trackEvent = (
eventName: string,
properties?: Record<string, unknown>,
): void => {
if (user && user.email) {
const context = {
context: {
groupId: extractDomain(user?.email),
},
};
const updatedProperties = { ...properties };
updatedProperties.userId = user.email;
window.analytics.track(eventName, properties, context);
}
};
return { trackPageView, trackEvent };
};
export default useAnalytics;

View File

@ -49,12 +49,10 @@
/>
<meta data-react-helmet="true" name="docusaurus_locale" content="en" />
<meta data-react-helmet="true" name="docusaurus_tag" content="default" />
<meta name="robots" content="noindex">
<meta name="robots" content="noindex" />
<link data-react-helmet="true" rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="/css/uPlot.min.css" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
@ -100,32 +98,16 @@
</script>
<script>
const CUSTOMERIO_ID = '<%= htmlWebpackPlugin.options.CUSTOMERIO_ID %>';
const CUSTOMERIO_SITE_ID = '<%= htmlWebpackPlugin.options.CUSTOMERIO_SITE_ID %>';
!function(){var i="cioanalytics", analytics=(window[i]=window[i]||[]);if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.setAttribute('data-global-customerio-analytics-key', i);t.src="https://cdp.customer.io/v1/analytics-js/snippet/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._writeKey=key;analytics._loadOptions=e};analytics.SNIPPET_VERSION="4.15.3";
analytics.load(
CUSTOMERIO_ID,
{
"integrations": {
"Customer.io In-App Plugin": {
siteId: CUSTOMERIO_SITE_ID
}
}
}
);
analytics.page();
}}();
</script>
<script>
//Set your SEGMENT_ID
const SEGMENT_ID = '<%= htmlWebpackPlugin.options.SEGMENT_ID %>';
const CUSTOMERIO_SITE_ID =
'<%= htmlWebpackPlugin.options.CUSTOMERIO_SITE_ID %>';
!(function () {
var analytics = (window.analytics = window.analytics || []);
var i = 'cioanalytics',
analytics = (window[i] = window[i] || []);
if (!analytics.initialize)
if (analytics.invoked)
window.console &&
console.error &&
console.error('Segment snippet included twice.');
console.error('Snippet included twice.');
else {
analytics.invoked = !0;
analytics.methods = [
@ -152,35 +134,36 @@
];
analytics.factory = function (e) {
return function () {
if (window.analytics.initialized)
return window.analytics[e].apply(window.analytics, arguments);
var i = Array.prototype.slice.call(arguments);
i.unshift(e);
analytics.push(i);
var t = Array.prototype.slice.call(arguments);
t.unshift(e);
analytics.push(t);
return analytics;
};
};
for (var i = 0; i < analytics.methods.length; i++) {
var key = analytics.methods[i];
for (var e = 0; e < analytics.methods.length; e++) {
var key = analytics.methods[e];
analytics[key] = analytics.factory(key);
}
analytics.load = function (key, i) {
analytics.load = function (key, e) {
var t = document.createElement('script');
t.type = 'text/javascript';
t.async = !0;
t.setAttribute('data-global-customerio-analytics-key', i);
t.src =
'https://analytics-cdn.signoz.io/analytics.js/v1/' +
'https://cdp.customer.io/v1/analytics-js/snippet/' +
key +
'/analytics.min.js';
var n = document.getElementsByTagName('script')[0];
n.parentNode.insertBefore(t, n);
analytics._loadOptions = i;
analytics._writeKey = key;
analytics._loadOptions = e;
};
analytics._writeKey = SEGMENT_ID;
analytics.SNIPPET_VERSION = '4.16.1';
analytics.load(SEGMENT_ID, {
analytics.SNIPPET_VERSION = '4.15.3';
analytics.load(CUSTOMERIO_ID, {
integrations: {
'Segment.io': { apiHost: 'analytics-api.signoz.io/v1' },
'Customer.io In-App Plugin': {
siteId: CUSTOMERIO_SITE_ID,
},
},
});
analytics.page();

View File

@ -21,7 +21,6 @@ const plugins = [
new HtmlWebpackPlugin({
template: 'src/index.html.ejs',
INTERCOM_APP_ID: process.env.INTERCOM_APP_ID,
SEGMENT_ID: process.env.SEGMENT_ID,
CUSTOMERIO_SITE_ID: process.env.CUSTOMERIO_SITE_ID,
CUSTOMERIO_ID: process.env.CUSTOMERIO_ID,
POSTHOG_KEY: process.env.POSTHOG_KEY,
@ -41,7 +40,6 @@ const plugins = [
FRONTEND_API_ENDPOINT: process.env.FRONTEND_API_ENDPOINT,
WEBSOCKET_API_ENDPOINT: process.env.WEBSOCKET_API_ENDPOINT,
INTERCOM_APP_ID: process.env.INTERCOM_APP_ID,
SEGMENT_ID: process.env.SEGMENT_ID,
CUSTOMERIO_SITE_ID: process.env.CUSTOMERIO_SITE_ID,
CUSTOMERIO_ID: process.env.CUSTOMERIO_ID,
POSTHOG_KEY: process.env.POSTHOG_KEY,

View File

@ -26,7 +26,6 @@ const plugins = [
new HtmlWebpackPlugin({
template: 'src/index.html.ejs',
INTERCOM_APP_ID: process.env.INTERCOM_APP_ID,
SEGMENT_ID: process.env.SEGMENT_ID,
CUSTOMERIO_SITE_ID: process.env.CUSTOMERIO_SITE_ID,
CUSTOMERIO_ID: process.env.CUSTOMERIO_ID,
POSTHOG_KEY: process.env.POSTHOG_KEY,
@ -51,7 +50,6 @@ const plugins = [
FRONTEND_API_ENDPOINT: process.env.FRONTEND_API_ENDPOINT,
WEBSOCKET_API_ENDPOINT: process.env.WEBSOCKET_API_ENDPOINT,
INTERCOM_APP_ID: process.env.INTERCOM_APP_ID,
SEGMENT_ID: process.env.SEGMENT_ID,
CUSTOMERIO_SITE_ID: process.env.CUSTOMERIO_SITE_ID,
CUSTOMERIO_ID: process.env.CUSTOMERIO_ID,
POSTHOG_KEY: process.env.POSTHOG_KEY,