UNPKG

5.72 kBJavaScriptView Raw
1/**
2 * Copyright 2017-2018 F5 Networks, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17'use strict';
18
19
20const uuid = require('uuid5');
21const q = require('q');
22const httpUtil = require('./httpUtil');
23const Logger = require('./logger');
24
25let logger = Logger.getLogger({
26 logLevel: 'none',
27 module
28});
29
30/**
31 * @module
32 */
33module.exports = {
34 upload(metrics) {
35 // upload to both google analytics and the ESE analytics service
36 return q.all([
37 eseAnalyticsUpload(metrics),
38 googleAnalyticsUpload(metrics)
39 ])
40 .then(() => {
41 return q.resolve('Metrics sent');
42 })
43 .catch((err) => {
44 // do not reject, just log
45 logger.error('Metrics upload error:', err && err.message ? err.message : err);
46 });
47 },
48
49 setLogger(aLogger) {
50 logger = aLogger;
51 },
52
53 setLoggerOptions(loggerOptions) {
54 const loggerOpts = Object.assign({}, loggerOptions);
55 loggerOpts.module = module;
56 logger = Logger.getLogger(loggerOpts);
57 }
58};
59
60function eseAnalyticsUpload(metrics) {
61 const userAgent = 'F5CloudLibs/1.0';
62 const getEndpointUrl = 'https://s3-us-west-1.amazonaws.com/eseanalytics/v1/info';
63 const getEndpointHeaders = {
64 'User-Agent': userAgent
65 };
66 const headers = {
67 'User-Agent': userAgent,
68 'Content-Type': 'application/json',
69 'x-api-key': 'klNnqVfprt8wWMmoNZIsa9GABxari6Y33K0JBkX6' // shared key for public service
70 };
71
72 // first query service containing endpoint
73 return httpUtil.get(getEndpointUrl, { headers: getEndpointHeaders })
74 .then((data) => {
75 // expected output: { primaryEndpoint: 'url' }
76 const endpoint = data ? data.primaryEndpoint : undefined;
77 if (!endpoint) throw new Error('Missing endpoint');
78
79 // certain values in data use OR operator to account for existing syntax
80 const body = {
81 metadata: {
82 service: 'cloud_templates',
83 type: 'JSON',
84 timestamp: new Date().toISOString(),
85 syntheticTest: metrics.syntheticTest || false
86 },
87 data: {
88 customerId: metrics.customerId,
89 deploymentId: metrics.deploymentId,
90 solutionName: metrics.solutionName || metrics.templateName,
91 solutionVersion: metrics.solutionVersion || metrics.templateVersion,
92 licenseType: metrics.licenseType,
93 platformName: metrics.platformName || metrics.cloudName,
94 platformRegion: metrics.platformRegion || metrics.region,
95 hostVersion: metrics.hostVersion || metrics.bigIpVersion,
96 cloudLibsVersion: metrics.cloudLibsVersion,
97 cloudLibsAction: metrics.action
98 }
99 };
100 return httpUtil.post(endpoint, { body, headers });
101 })
102 .catch((error) => {
103 return q.reject(error);
104 });
105}
106
107function addMetricsComponent(payload, metric, data, maxLength) {
108 let mungedData = data;
109 if (mungedData) {
110 if (maxLength && mungedData.length > maxLength) {
111 mungedData = mungedData.substr(0, maxLength);
112 }
113 return `${payload}&${metric}=${encodeURIComponent(mungedData)}`;
114 }
115
116 return payload;
117}
118
119function googleAnalyticsUpload(metrics) {
120 const METRICS_URL = 'https://www.google-analytics.com/collect';
121 const headers = {
122 'User-Agent': 'Mozilla/5.0'
123 };
124 const METRICS_TRACKING_ID = 'UA-47575237-11';
125
126 let payload = '';
127
128 if (!metrics.customerId) {
129 return q.reject(new Error('customer id is required'));
130 }
131
132 const customerUuid = uuid(metrics.customerId);
133
134 payload = addMetricsComponent(payload, 'v', '1');
135 payload = addMetricsComponent(payload, 't', 'event');
136 payload = addMetricsComponent(payload, 'ec', 'run', 150);
137 payload = addMetricsComponent(payload, 'tid', METRICS_TRACKING_ID);
138 payload = addMetricsComponent(payload, 'cid', customerUuid, 150);
139 // customerUuid added here too because cid is not visible to queries
140 payload = addMetricsComponent(payload, 'aiid', customerUuid, 150);
141 payload = addMetricsComponent(payload, 'ea', metrics.action || 'unknown', 500);
142 payload = addMetricsComponent(payload, 'an', metrics.templateName, 100);
143 payload = addMetricsComponent(payload, 'aid', metrics.deploymentId, 150);
144 payload = addMetricsComponent(payload, 'av', metrics.templateVersion, 100);
145 payload = addMetricsComponent(payload, 'cn', metrics.cloudName, 100);
146 payload = addMetricsComponent(payload, 'cm', metrics.region, 50);
147 payload = addMetricsComponent(payload, 'cs', metrics.bigIpVersion, 100);
148 payload = addMetricsComponent(payload, 'ck', metrics.licenseType, 500);
149 payload = addMetricsComponent(payload, 'ds', metrics.cloudLibsVersion);
150
151 logger.silly('sending metrics payload:', payload);
152 return httpUtil.post(
153 METRICS_URL,
154 {
155 body: payload,
156 headers
157 }
158 );
159}