-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #274 from atlassian/ARC-2825-be-analytics
ARC-2825 be analytics
- Loading branch information
Showing
20 changed files
with
1,822 additions
and
941 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { isProductionEnv, createAnonymousId, getAccountDetails } from './analytics-client'; | ||
|
||
jest.mock('./analytics-client', () => ({ | ||
...jest.requireActual('./analytics-client'), | ||
getAnalyticsClient: jest.fn().mockReturnValue({ cats: 'ssss' }) | ||
})); | ||
|
||
jest.mock('@atlassiansox/analytics-node-client'); | ||
|
||
describe('isProductionEnv', () => { | ||
test('should return true for production environment', () => { | ||
process.env.NODE_ENV = 'prod'; | ||
expect(isProductionEnv()).toBe(true); | ||
}); | ||
test('should return true for production environment', () => { | ||
process.env.NODE_ENV = 'somethingelse'; | ||
expect(isProductionEnv()).toBe(false); | ||
}); | ||
}); | ||
describe('createAnonymousId', () => { | ||
test('should create a hashed anonymousId', () => { | ||
const result = createAnonymousId('testInput'); | ||
expect(result).toBe('620ae460798e1f4cab44c44f3085620284f0960a276bbc3f0bd416449df14dbe'); | ||
}); | ||
}); | ||
describe('getAccountDetails', () => { | ||
test('should return anonymousId when no accountId', () => { | ||
const result = getAccountDetails('', 'ipAddress'); | ||
expect(result).toEqual({ | ||
anonymousId: '095cf3ff5683bd7c1db48018af7d0bee79205bcafb47a09b97f9faf0bcee4800' | ||
}); | ||
}); | ||
test('should return accountId object', () => { | ||
const result = getAccountDetails('testAccount'); | ||
expect(result).toEqual({ | ||
userIdType: 'atlassianAccount', | ||
userId: 'testAccount', | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import crypto from 'crypto'; | ||
|
||
interface AnalyticsAttributes { | ||
[key: string]: any; | ||
} | ||
|
||
interface EventPayload { | ||
eventName: string, | ||
action: string, | ||
actionSubject: string, | ||
attributes?: AnalyticsAttributes | ||
} | ||
|
||
enum EnvType { | ||
LOCAL = 'local', | ||
DEV = 'dev', | ||
STAGING = 'staging', | ||
PROD = 'prod' | ||
} | ||
|
||
// eslint-disable-next-line max-len | ||
export const sendAnalytics = async (cloudId: string, eventPayload: EventPayload, accountId?: string, anonymousId?: string): Promise<void> => { | ||
sendEvent(cloudId, eventPayload, accountId, anonymousId) | ||
.then(() => console.log('Analytics event processed')) | ||
.catch((e) => console.error({ e }, 'Failed to send analytics event')); | ||
}; | ||
|
||
// eslint-disable-next-line max-len | ||
const sendEvent = async (cloudId: string, eventPayload: EventPayload, accountId?: string, anonymousId?: string): Promise<void> => { | ||
const analyticsClient = await getAnalyticsClient(); | ||
const { | ||
eventName, attributes, actionSubject, action | ||
} = eventPayload; | ||
|
||
if (!analyticsClient || !isProductionEnv()) { | ||
console.warn('Analytics sendEvent skipped: @atlassiansox/analytics-node-client module not found or environment not production.'); | ||
return; | ||
} | ||
|
||
const accountDetails = getAccountDetails(accountId, anonymousId); | ||
|
||
await analyticsClient.sendTrackEvent({ | ||
...accountDetails, | ||
tenantIdType: 'cloudId', | ||
tenantId: cloudId, | ||
trackEvent: { | ||
source: eventName, | ||
action: action || 'unknown', | ||
actionSubject: actionSubject || eventName, | ||
attributes: { | ||
...attributes | ||
} | ||
} | ||
}); | ||
}; | ||
|
||
export const isProductionEnv = (): boolean => { | ||
const env = (process.env.NODE_ENV || '').toLowerCase(); | ||
return ['production', 'prod'].includes(env); | ||
}; | ||
|
||
export const getAccountDetails = (accountId?: string, anonymousId?: string) => { | ||
if (accountId) { | ||
return { | ||
userIdType: 'atlassianAccount', | ||
userId: accountId, | ||
}; | ||
} | ||
const hashedAnonymousId = createAnonymousId(anonymousId || 'default'); | ||
return { anonymousId: hashedAnonymousId }; | ||
}; | ||
|
||
export const createAnonymousId = (input: string): string => { | ||
const hash = crypto.createHash('sha256').update(input).digest('hex'); | ||
return hash; | ||
}; | ||
|
||
export const getAnalyticsClient = async (): Promise<any> => { | ||
try { | ||
const { analyticsClient } = await import('@atlassiansox/analytics-node-client'); | ||
|
||
const analyticsNodeClient = analyticsClient({ | ||
env: EnvType.PROD, | ||
product: 'jenkinsForJira' | ||
}); | ||
|
||
return analyticsNodeClient; | ||
} catch (error) { | ||
return null; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// All variables below were defined by DataPortal. Do not change their values | ||
// as it will affect our metrics logs and dashboards. | ||
export enum AnalyticsEventTypes { | ||
ScreenEvent = 'screen', // user navigates to a particular screen, tab, drawer, modal, or inline-dialog | ||
UiEvent = 'ui', // user interacts with a user interface element such as a button, text field, or link | ||
TrackEvent = 'track', // user completes a product action e.g. submits form | ||
OperationalEvent = 'operational' // help measure usages or performance of implementation detail | ||
} | ||
|
||
export enum AnalyticsTrackEventsEnum { | ||
ConfigDataReceivedName = 'ConfigDataReceived', | ||
DisconnectedServerName = 'DisconnectedServer', | ||
ConnectionCreatedName = 'ConnectionCreated' | ||
} | ||
|
||
export enum AnalyticsOperationalEventsEnum {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// All variables below were defined by DataPortal. | ||
// Do not change their values as it will affect our metrics logs and dashboards. | ||
export enum AnalyticsEventTypes { | ||
ScreenEvent = 'screen', // user navigates to a particular screen, tab, drawer, modal, or inline-dialog | ||
UiEvent = 'ui', // user interacts with a user interface element such as a button, text field, or link | ||
TrackEvent = 'track', // user completes a product action e.g. submits form | ||
OperationalEvent = 'operational' // help measure usages or performance of implementation detail | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.