Skip to content

Switch performance event traffic to transport endpoint #2593

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

Merged
merged 14 commits into from
Apr 8, 2020
Merged
Show file tree
Hide file tree
Changes from 5 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
3 changes: 3 additions & 0 deletions packages/performance/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Unreleased
- [changed] Enable new performance monitoring users to onboard in real time.

# 0.2.30
- [changed] Internal transport protocol update from proto2 to proto3.
74 changes: 74 additions & 0 deletions packages/performance/src/services/perf_logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { SDK_VERSION } from '../constants';
import * as attributeUtils from '../utils/attributes_utils';
import { createNetworkRequestEntry } from '../resources/network_request';
import '../../test/setup';
import { mergeStrings } from '../utils/string_merger';

describe('Performance Monitoring > perf_logger', () => {
const IID = 'idasdfsffe';
Expand Down Expand Up @@ -301,5 +302,78 @@ describe('Performance Monitoring > perf_logger', () => {
EXPECTED_NETWORK_MESSAGE
);
});

it('Skip performance collection if domain is cc', () => {
const CC_NETWORK_PERFORMANCE_ENTRY: PerformanceResourceTiming = {
connectEnd: 0,
connectStart: 0,
decodedBodySize: 0,
domainLookupEnd: 0,
domainLookupStart: 0,
duration: 39.610000094398856,
encodedBodySize: 0,
entryType: 'resource',
fetchStart: 5645.689999917522,
initiatorType: 'fetch',
name: 'http://firebaselogging.googleapis.com/some/path?message=a',
nextHopProtocol: 'http/2+quic/43',
redirectEnd: 0,
redirectStart: 0,
requestStart: 0,
responseEnd: 5685.300000011921,
responseStart: 0,
secureConnectionStart: 0,
startTime: 5645.689999917522,
transferSize: 0,
workerStart: 0,
toJSON: () => {}
};
getIidStub.returns(IID);
SettingsService.getInstance().loggingEnabled = true;
SettingsService.getInstance().logNetworkAfterSampling = true;
// Calls logNetworkRequest under the hood.
createNetworkRequestEntry(CC_NETWORK_PERFORMANCE_ENTRY);
clock.tick(1);

expect(addToQueueStub).not.called;
});

it('Skip performance collection if domain is transport', () => {
const TRANSPORT_NETWORK_PERFORMANCE_ENTRY: PerformanceResourceTiming = {
connectEnd: 0,
connectStart: 0,
decodedBodySize: 0,
domainLookupEnd: 0,
domainLookupStart: 0,
duration: 39.610000094398856,
encodedBodySize: 0,
entryType: 'resource',
fetchStart: 5645.689999917522,
initiatorType: 'fetch',
name: mergeStrings(
'hts/frbslgigp.ogepscmti/sapt?aa=2',
'tp:/ieaeogn-agolai.o/hsi//ahprm13'
),
nextHopProtocol: 'http/2+quic/43',
redirectEnd: 0,
redirectStart: 0,
requestStart: 0,
responseEnd: 5685.300000011921,
responseStart: 0,
secureConnectionStart: 0,
startTime: 5645.689999917522,
transferSize: 0,
workerStart: 0,
toJSON: () => {}
};
getIidStub.returns(IID);
SettingsService.getInstance().loggingEnabled = true;
SettingsService.getInstance().logNetworkAfterSampling = true;
// Calls logNetworkRequest under the hood.
createNetworkRequestEntry(TRANSPORT_NETWORK_PERFORMANCE_ENTRY);
clock.tick(1);

expect(addToQueueStub).not.called;
});
});
});
18 changes: 16 additions & 2 deletions packages/performance/src/services/perf_logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,22 @@ export function logNetworkRequest(networkRequest: NetworkRequest): void {
if (!settingsService.instrumentationEnabled) {
return;
}
// Do not log the js sdk's call to cc service to avoid unnecessary cycle.
if (networkRequest.url === settingsService.logEndPointUrl.split('?')[0]) {

// Do not log the js sdk's call to transport service domain to avoid unnecessary cycle.
// Need to blacklist both old and new endpoints to avoid migration gap.
const networkRequestHostName = new URL(networkRequest.url).hostname;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL API is not available in IE11. Are you able to just use string parsing? I'm reluctant to ask people to add an additional polyfill unless there is a strong reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the heads-up! Decided not to use URL API and match the full URL without search parameter for cc and fl endpoints.


// Blacklist old log endpoint.
const logEndpointHostName = new URL(settingsService.logEndPointUrl).hostname;
if (networkRequestHostName === logEndpointHostName) {
return;
}

// Blacklist new transport endpoint.
const transportEndpointHostName = new URL(
settingsService.transportEndpointUrl
).hostname;
if (networkRequestHostName === transportEndpointHostName) {
return;
}

Expand Down
133 changes: 128 additions & 5 deletions packages/performance/src/services/remote_config_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,18 @@ describe('Performance Monitoring > remote_config_service', () => {
const IID = 'asd123';
const AUTH_TOKEN = 'auth_token';
const LOG_URL = 'https://firebaselogging.test.com';
const TRANSPORT_KEY = 'pseudo-transport-key';
const LOG_SOURCE = 2;
const NETWORK_SAMPLIG_RATE = 0.25;
const TRACE_SAMPLING_RATE = 0.5;
const GLOBAL_CLOCK_NOW = 1556524895326;
const STRINGIFIED_CONFIG = `{"entries":{"fpr_enabled":"true",\
"fpr_log_endpoint_url":"https://firebaselogging.test.com",\
"fpr_log_source":"2","fpr_vc_network_request_sampling_rate":"0.250000",\
"fpr_vc_session_sampling_rate":"0.250000","fpr_vc_trace_sampling_rate":"0.500000"},\
"state":"UPDATE"}`;
"fpr_log_endpoint_url":"https://firebaselogging.test.com",\
"fpr_log_transport_key":"pseudo-transport-key",\
"fpr_log_source":"2","fpr_vc_network_request_sampling_rate":"0.250000",\
"fpr_log_transport_web_percent":"100.0",\
"fpr_vc_session_sampling_rate":"0.250000","fpr_vc_trace_sampling_rate":"0.500000"},\
"state":"UPDATE"}`;
const PROJECT_ID = 'project1';
const APP_ID = '1:23r:web:fewq';
const API_KEY = 'asdfghjk';
Expand Down Expand Up @@ -127,7 +130,11 @@ describe('Performance Monitoring > remote_config_service', () => {
expect(getItemStub).to.be.called;
expect(SettingsService.getInstance().loggingEnabled).to.be.true;
expect(SettingsService.getInstance().logEndPointUrl).to.equal(LOG_URL);
expect(SettingsService.getInstance().transportKey).to.equal(
TRANSPORT_KEY
);
expect(SettingsService.getInstance().logSource).to.equal(LOG_SOURCE);
expect(SettingsService.getInstance().shouldSendToTransport).to.be.true;
expect(
SettingsService.getInstance().networkRequestsSamplingRate
).to.equal(NETWORK_SAMPLIG_RATE);
Expand Down Expand Up @@ -164,7 +171,11 @@ describe('Performance Monitoring > remote_config_service', () => {
expect(getItemStub).to.be.calledOnce;
expect(SettingsService.getInstance().loggingEnabled).to.be.true;
expect(SettingsService.getInstance().logEndPointUrl).to.equal(LOG_URL);
expect(SettingsService.getInstance().transportKey).to.equal(
TRANSPORT_KEY
);
expect(SettingsService.getInstance().logSource).to.equal(LOG_SOURCE);
expect(SettingsService.getInstance().shouldSendToTransport).to.be.true;
expect(
SettingsService.getInstance().networkRequestsSamplingRate
).to.equal(NETWORK_SAMPLIG_RATE);
Expand Down Expand Up @@ -214,7 +225,7 @@ describe('Performance Monitoring > remote_config_service', () => {
it('uses secondary configs if the response does not have any fields', async () => {
// Expired local config.
const EXPIRY_LOCAL_STORAGE_VALUE = '1556524895320';
const STRINGIFIED_PARTIAL_CONFIG = '{"state":"NO TEMPLATE"}';
const STRINGIFIED_PARTIAL_CONFIG = '{"state":"NO_TEMPLATE"}';

setup(
{
Expand All @@ -228,4 +239,116 @@ describe('Performance Monitoring > remote_config_service', () => {
expect(SettingsService.getInstance().loggingEnabled).to.be.true;
});
});

describe('Transport rollout flag', () => {
it('No template', async () => {
setup(
{
// Expired local config.
expiry: '1556524895320',
config: 'not a valid config and should not be used'
},
{ reject: false, value: new Response('{"state":"NO_TEMPLATE"}') }
);
await getConfig(IID);

// If no template, will send to cc.
expect(SettingsService.getInstance().shouldSendToTransport).to.be.false;
});

it('state not specified', async () => {
setup(
{
// Expired local config.
expiry: '1556524895320',
config: 'not a valid config and should not be used'
},
{
reject: false,
value: new Response('{"state":"INSTANCE_STATE_UNSPECIFIED"}')
}
);
await getConfig(IID);

// If no template, will send to cc.
expect(SettingsService.getInstance().shouldSendToTransport).to.be.false;
});

it('state not exists', async () => {
setup(
{
// Expired local config.
expiry: '1556524895320',
config: 'not a valid config and should not be used'
},
{ reject: false, value: new Response('{}') }
);
await getConfig(IID);

// If no template, will send to cc.
expect(SettingsService.getInstance().shouldSendToTransport).to.be.false;
});

it('Template exists but no rollout flag', async () => {
const CONFIG_WITHOUT_ROLLOUT_FLAG = `{"entries":{"fpr_enabled":"true",\
"fpr_log_endpoint_url":"https://firebaselogging.test.com",\
"fpr_log_source":"2","fpr_vc_network_request_sampling_rate":"0.250000",\
"fpr_vc_session_sampling_rate":"0.250000","fpr_vc_trace_sampling_rate":"0.500000"},\
"state":"UPDATE"}`;
setup(
{
// Expired local config.
expiry: '1556524895320',
config: 'not a valid config and should not be used'
},
{ reject: false, value: new Response(CONFIG_WITHOUT_ROLLOUT_FLAG) }
);
await getConfig(IID);

// If template exists but no rollout flag, will send to transport.
expect(SettingsService.getInstance().shouldSendToTransport).to.be.true;
});

it('Rollout flag exists and sends to cc', async () => {
const CONFIG_WITH_ROLLOUT_FLAG_10 = `{"entries":{"fpr_enabled":"true",\
"fpr_log_endpoint_url":"https://firebaselogging.test.com",\
"fpr_log_source":"2","fpr_vc_network_request_sampling_rate":"0.250000",\
"fpr_log_transport_web_percent":"10.0",\
"fpr_vc_session_sampling_rate":"0.250000","fpr_vc_trace_sampling_rate":"0.500000"},\
"state":"UPDATE"}`;
setup(
{
// Expired local config.
expiry: '1556524895320',
config: 'not a valid config and should not be used'
},
{ reject: false, value: new Response(CONFIG_WITH_ROLLOUT_FLAG_10) }
);
await getConfig(IID);

// If template exists but no rollout flag, will send to transport.
expect(SettingsService.getInstance().shouldSendToTransport).to.be.false;
});

it('Rollout flag exists and sends to transport', async () => {
const CONFIG_WITH_ROLLOUT_FLAG_40 = `{"entries":{"fpr_enabled":"true",\
"fpr_log_endpoint_url":"https://firebaselogging.test.com",\
"fpr_log_source":"2","fpr_vc_network_request_sampling_rate":"0.250000",\
"fpr_log_transport_web_percent":"40.0",\
"fpr_vc_session_sampling_rate":"0.250000","fpr_vc_trace_sampling_rate":"0.500000"},\
"state":"UPDATE"}`;
setup(
{
// Expired local config.
expiry: '1556524895320',
config: 'not a valid config and should not be used'
},
{ reject: false, value: new Response(CONFIG_WITH_ROLLOUT_FLAG_40) }
);
await getConfig(IID);

// If template exists but no rollout flag, will send to transport.
expect(SettingsService.getInstance().shouldSendToTransport).to.be.true;
});
});
});
Loading