Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tracking) Configure whether mixpanel is enabled with env variable #4768

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
import com.linkedin.metadata.models.registry.EntityRegistry;
import com.linkedin.metadata.recommendation.RecommendationsService;
import com.linkedin.metadata.secret.SecretService;
import com.linkedin.metadata.telemetry.TelemetryConfiguration;
import com.linkedin.metadata.timeseries.TimeseriesAspectService;
import com.linkedin.metadata.version.GitVersion;
import com.linkedin.usage.UsageClient;
Expand Down Expand Up @@ -221,6 +222,7 @@ public class GmsGraphQLEngine {
private final AuthenticationConfiguration authenticationConfiguration;
private final AuthorizationConfiguration authorizationConfiguration;
private final VisualConfiguration visualConfiguration;
private final TelemetryConfiguration telemetryConfiguration;

private final DatasetType datasetType;
private final CorpUserType corpUserType;
Expand Down Expand Up @@ -287,7 +289,8 @@ public GmsGraphQLEngine(
final AuthorizationConfiguration authorizationConfiguration,
final GitVersion gitVersion,
final boolean supportsImpactAnalysis,
final VisualConfiguration visualConfiguration
final VisualConfiguration visualConfiguration,
final TelemetryConfiguration telemetryConfiguration
) {

this.entityClient = entityClient;
Expand All @@ -308,6 +311,7 @@ public GmsGraphQLEngine(
this.authenticationConfiguration = Objects.requireNonNull(authenticationConfiguration);
this.authorizationConfiguration = Objects.requireNonNull(authorizationConfiguration);
this.visualConfiguration = visualConfiguration;
this.telemetryConfiguration = telemetryConfiguration;

this.datasetType = new DatasetType(entityClient);
this.corpUserType = new CorpUserType(entityClient);
Expand Down Expand Up @@ -476,7 +480,7 @@ private void configureQueryResolvers(final RuntimeWiring.Builder builder) {
this.ingestionConfiguration,
this.authenticationConfiguration,
this.authorizationConfiguration,
supportsImpactAnalysis, this.visualConfiguration))
supportsImpactAnalysis, this.visualConfiguration, this.telemetryConfiguration))
.dataFetcher("me", new MeResolver(this.entityClient))
.dataFetcher("search", new SearchResolver(this.entityClient))
.dataFetcher("searchAcrossEntities", new SearchAcrossEntitiesResolver(this.entityClient))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
import com.linkedin.datahub.graphql.generated.PoliciesConfig;
import com.linkedin.datahub.graphql.generated.Privilege;
import com.linkedin.datahub.graphql.generated.ResourcePrivileges;
import com.linkedin.datahub.graphql.generated.TelemetryConfig;
import com.linkedin.datahub.graphql.generated.VisualConfiguration;
import com.linkedin.metadata.config.IngestionConfiguration;
import com.linkedin.metadata.telemetry.TelemetryConfiguration;
import com.linkedin.metadata.version.GitVersion;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
Expand All @@ -34,6 +36,7 @@ public class AppConfigResolver implements DataFetcher<CompletableFuture<AppConfi
private final AuthorizationConfiguration _authorizationConfiguration;
private final boolean _supportsImpactAnalysis;
private final VisualConfiguration _visualConfiguration;
private final TelemetryConfiguration _telemetryConfiguration;

public AppConfigResolver(
final GitVersion gitVersion,
Expand All @@ -42,14 +45,16 @@ public AppConfigResolver(
final AuthenticationConfiguration authenticationConfiguration,
final AuthorizationConfiguration authorizationConfiguration,
final boolean supportsImpactAnalysis,
final VisualConfiguration visualConfiguration) {
final VisualConfiguration visualConfiguration,
final TelemetryConfiguration telemetryConfiguration) {
_gitVersion = gitVersion;
_isAnalyticsEnabled = isAnalyticsEnabled;
_ingestionConfiguration = ingestionConfiguration;
_authenticationConfiguration = authenticationConfiguration;
_authorizationConfiguration = authorizationConfiguration;
_supportsImpactAnalysis = supportsImpactAnalysis;
_visualConfiguration = visualConfiguration;
_telemetryConfiguration = telemetryConfiguration;
}

@Override
Expand Down Expand Up @@ -98,6 +103,10 @@ public CompletableFuture<AppConfig> get(final DataFetchingEnvironment environmen
appConfig.setAuthConfig(authConfig);
appConfig.setVisualConfig(_visualConfiguration);

final TelemetryConfig telemetryConfig = new TelemetryConfig();
telemetryConfig.setEnableThirdPartyLogging(_telemetryConfiguration.isEnableThirdPartyLogging());
appConfig.setTelemetryConfig(telemetryConfig);

return CompletableFuture.completedFuture(appConfig);
}

Expand Down
15 changes: 15 additions & 0 deletions datahub-graphql-core/src/main/resources/app.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ type AppConfig {
Configurations related to visual appearance, allows styling the UI without rebuilding the bundle
"""
visualConfig: VisualConfiguration!

"""
Configurations related to tracking users in the app
"""
telemetryConfig: TelemetryConfig!
}

"""
Expand All @@ -124,6 +129,16 @@ type VisualConfiguration {
logoUrl: String
}

"""
Configurations related to tracking users in the app
"""
type TelemetryConfig {
"""
Env variable for whether or not third party logging should be enabled for this instance
"""
enableThirdPartyLogging: Boolean
}

"""
Configurations related to Lineage
"""
Expand Down
15 changes: 14 additions & 1 deletion datahub-web-react/src/AppConfigProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';
import React, { useEffect } from 'react';
import './App.less';
import { THIRD_PARTY_LOGGING_KEY } from './app/analytics/analytics';
import { checkAuthStatus } from './app/auth/checkAuthStatus';
import { AppConfigContext, DEFAULT_APP_CONFIG } from './appConfigContext';
import { useAppConfigQuery } from './graphql/app.generated';

Expand All @@ -10,6 +12,17 @@ const AppConfigProvider = ({ children }: { children: React.ReactNode }) => {
refetch();
};

useEffect(() => {
if (appConfigData && appConfigData.appConfig) {
if (appConfigData.appConfig.telemetryConfig.enableThirdPartyLogging) {
localStorage.setItem(THIRD_PARTY_LOGGING_KEY, 'true');
checkAuthStatus(); // identify in analyitcs once we receive config response
} else {
localStorage.setItem(THIRD_PARTY_LOGGING_KEY, 'false');
}
}
}, [appConfigData]);

return (
<AppConfigContext.Provider
value={{ config: appConfigData?.appConfig || DEFAULT_APP_CONFIG, refreshContext: refreshAppConfig }}
Expand Down
29 changes: 29 additions & 0 deletions datahub-web-react/src/app/analytics/__tests__/analytics.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { getMergedTrackingOptions, THIRD_PARTY_LOGGING_KEY } from '../analytics';

describe('getMergedTrackingOptions', () => {
it('should update or create an options object with mixpanel set to the value of what is in localStorage', () => {
// before anything is set in localStorage
let trackingOptions = getMergedTrackingOptions();
expect(trackingOptions).toMatchObject({
plugins: {
mixpanel: false,
},
});

localStorage.setItem(THIRD_PARTY_LOGGING_KEY, 'false');
trackingOptions = getMergedTrackingOptions();
expect(trackingOptions).toMatchObject({
plugins: {
mixpanel: false,
},
});

localStorage.setItem(THIRD_PARTY_LOGGING_KEY, 'true');
trackingOptions = getMergedTrackingOptions();
expect(trackingOptions).toMatchObject({
plugins: {
mixpanel: true,
},
});
});
});
25 changes: 22 additions & 3 deletions datahub-web-react/src/app/analytics/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,28 @@ import { getBrowserId } from '../browserId';

const appName = 'datahub-react';

export const THIRD_PARTY_LOGGING_KEY = 'enableThirdPartyLogging';

const analytics = Analytics({
app: appName,
plugins: plugins.filter((plugin) => plugin.isEnabled).map((plugin) => plugin.plugin),
});

const { NODE_ENV } = process.env;

export function getMergedTrackingOptions(options?: any) {
jjoyce0510 marked this conversation as resolved.
Show resolved Hide resolved
const isThirdPartyLoggingEnabled = JSON.parse(localStorage.getItem(THIRD_PARTY_LOGGING_KEY) || 'false');
return {
...options,
plugins: {
mixpanel: isThirdPartyLoggingEnabled,
amplitude: isThirdPartyLoggingEnabled,
googleAnalytics: isThirdPartyLoggingEnabled,
},
};
}

export default {
...analytics,
page: (data?: PageData, options?: any, callback?: (...params: any[]) => any) => {
const modifiedData = {
...data,
Expand All @@ -29,7 +42,8 @@ export default {
if (NODE_ENV === 'test') {
return null;
}
return analytics.page(modifiedData, options, callback);
const trackingOptions = getMergedTrackingOptions(options);
return analytics.page(modifiedData, trackingOptions, callback);
},
event: (event: Event, options?: any, callback?: (...params: any[]) => any): Promise<any> => {
const eventTypeName = EventType[event.type];
Expand All @@ -45,6 +59,11 @@ export default {
if (NODE_ENV === 'test') {
return Promise.resolve();
}
return analytics.track(eventTypeName, modifiedEvent, options, callback);
const trackingOptions = getMergedTrackingOptions(options);
return analytics.track(eventTypeName, modifiedEvent, trackingOptions, callback);
},
identify: (userId: string, traits?: any, options?: any, callback?: ((...params: any[]) => any) | undefined) => {
jjoyce0510 marked this conversation as resolved.
Show resolved Hide resolved
const trackingOptions = getMergedTrackingOptions(options);
return analytics.identify(userId, traits, trackingOptions, callback);
},
};
3 changes: 3 additions & 0 deletions datahub-web-react/src/appConfigContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export const DEFAULT_APP_CONFIG = {
authConfig: {
tokenAuthEnabled: false,
},
telemetryConfig: {
enableThirdPartyLogging: false,
},
};

export const AppConfigContext = React.createContext<{
Expand Down
3 changes: 3 additions & 0 deletions datahub-web-react/src/graphql/app.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ query appConfig {
visualConfig {
logoUrl
}
telemetryConfig {
enableThirdPartyLogging
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.linkedin.gms.factory.config;
package com.linkedin.metadata.telemetry;

import lombok.Data;
/**
Expand All @@ -14,4 +14,8 @@ public class TelemetryConfiguration {
* Whether reporting telemetry is enabled
*/
public boolean enabledIngestion;
/**
* Whether or not third party logging should be enabled for this instance
*/
public boolean enableThirdPartyLogging;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.datahub.authentication.AuthenticationConfiguration;
import com.datahub.authorization.AuthorizationConfiguration;
import com.linkedin.metadata.config.IngestionConfiguration;
import com.linkedin.metadata.telemetry.TelemetryConfiguration;
import com.linkedin.gms.factory.spring.YamlPropertySourceFactory;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ protected GraphQLEngine getInstance() {
_configProvider.getAuthorization(),
_gitVersion,
_graphService.supportsMultiHop(),
_visualConfiguration
_visualConfiguration,
_configProvider.getTelemetry()
).builder().build();
}
return new GmsGraphQLEngine(
Expand All @@ -139,7 +140,8 @@ protected GraphQLEngine getInstance() {
_configProvider.getAuthorization(),
_gitVersion,
_graphService.supportsMultiHop(),
_visualConfiguration
_visualConfiguration,
_configProvider.getTelemetry()
).builder().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ ingestion:
telemetry:
enabledCli: ${CLI_TELEMETRY_ENABLED:true}
enabledIngestion: ${INGESTION_REPORTING_ENABLED:false}
enableThirdPartyLogging: ${ENABLE_THIRD_PARTY_LOGGING:false}

secretService:
encryptionKey: ${SECRET_SERVICE_ENCRYPTION_KEY:ENCRYPTION_KEY}
Expand Down