airbyte-faros-destination 0.18.0 → 0.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AirbyteRecord } from 'faros-airbyte-cdk';
|
|
2
|
+
import { DestinationModel, DestinationRecord, StreamContext } from '../converter';
|
|
3
|
+
import { CircleCIConverter } from './common';
|
|
4
|
+
export declare class Usage extends CircleCIConverter {
|
|
5
|
+
readonly destinationModels: ReadonlyArray<DestinationModel>;
|
|
6
|
+
private static readonly METRIC_DEFINITION_UID;
|
|
7
|
+
private static metricDefinitionWritten;
|
|
8
|
+
private readonly axios;
|
|
9
|
+
convert(record: AirbyteRecord, ctx: StreamContext): Promise<ReadonlyArray<DestinationRecord>>;
|
|
10
|
+
private downloadAndParseCsv;
|
|
11
|
+
private convertCsvToMetricValues;
|
|
12
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Usage = void 0;
|
|
37
|
+
const sync_1 = require("csv-parse/sync");
|
|
38
|
+
const faros_airbyte_cdk_1 = require("faros-airbyte-cdk");
|
|
39
|
+
const faros_js_client_1 = require("faros-js-client");
|
|
40
|
+
const zlib = __importStar(require("zlib"));
|
|
41
|
+
const common_1 = require("./common");
|
|
42
|
+
// Credit types from CircleCI usage CSV
|
|
43
|
+
const CREDIT_TYPES = [
|
|
44
|
+
'COMPUTE_CREDITS',
|
|
45
|
+
'DLC_CREDITS',
|
|
46
|
+
'USER_CREDITS',
|
|
47
|
+
'STORAGE_CREDITS',
|
|
48
|
+
'NETWORK_CREDITS',
|
|
49
|
+
'LEASE_CREDITS',
|
|
50
|
+
'LEASE_OVERAGE_CREDITS',
|
|
51
|
+
'IPRANGES_CREDITS',
|
|
52
|
+
'TOTAL_CREDITS',
|
|
53
|
+
];
|
|
54
|
+
class Usage extends common_1.CircleCIConverter {
|
|
55
|
+
constructor() {
|
|
56
|
+
super(...arguments);
|
|
57
|
+
this.destinationModels = [
|
|
58
|
+
'faros_MetricDefinition',
|
|
59
|
+
'faros_MetricValue',
|
|
60
|
+
];
|
|
61
|
+
this.axios = (0, faros_js_client_1.makeAxiosInstanceWithRetry)();
|
|
62
|
+
}
|
|
63
|
+
async convert(record, ctx) {
|
|
64
|
+
var _a;
|
|
65
|
+
const usage = record.record.data;
|
|
66
|
+
let res = [];
|
|
67
|
+
// Write metric definition once
|
|
68
|
+
if (!Usage.metricDefinitionWritten) {
|
|
69
|
+
res.push({
|
|
70
|
+
model: 'faros_MetricDefinition',
|
|
71
|
+
record: {
|
|
72
|
+
uid: Usage.METRIC_DEFINITION_UID,
|
|
73
|
+
name: 'CircleCI Job Usage',
|
|
74
|
+
description: 'Credit usage metrics by CircleCI jobs',
|
|
75
|
+
valueType: {
|
|
76
|
+
category: 'Numeric',
|
|
77
|
+
detail: 'Credits used per job, by type',
|
|
78
|
+
},
|
|
79
|
+
scorecardCompatible: false,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
Usage.metricDefinitionWritten = true;
|
|
83
|
+
}
|
|
84
|
+
// Only process completed exports with download URLs
|
|
85
|
+
if (usage.state !== 'completed' || !((_a = usage.download_urls) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
86
|
+
ctx.logger.info(`Skipping usage export job ${usage.usage_export_job_id} because it is not completed or has no download URLs`);
|
|
87
|
+
return res;
|
|
88
|
+
}
|
|
89
|
+
// Process each download URL (CSV file)
|
|
90
|
+
for (const downloadUrl of usage.download_urls) {
|
|
91
|
+
ctx.logger.info(`Processing CSV from job ${usage.usage_export_job_id}`);
|
|
92
|
+
try {
|
|
93
|
+
const csvData = await this.downloadAndParseCsv(downloadUrl, ctx);
|
|
94
|
+
const metricValues = this.convertCsvToMetricValues(csvData);
|
|
95
|
+
res = res.concat(metricValues);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
ctx.logger.error(`Failed to process CSV from job ${usage.usage_export_job_id} at ${downloadUrl}: ${error.message}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return res;
|
|
102
|
+
}
|
|
103
|
+
async downloadAndParseCsv(url, ctx) {
|
|
104
|
+
try {
|
|
105
|
+
// Download the CSV.gz file
|
|
106
|
+
const response = await this.axios.get(url, {
|
|
107
|
+
responseType: 'arraybuffer',
|
|
108
|
+
});
|
|
109
|
+
const buffer = Buffer.from(response.data);
|
|
110
|
+
// Decompress the gzipped CSV
|
|
111
|
+
const csvContent = zlib.gunzipSync(buffer).toString('utf8');
|
|
112
|
+
// Parse the CSV
|
|
113
|
+
const records = (0, sync_1.parse)(csvContent, {
|
|
114
|
+
columns: true,
|
|
115
|
+
skip_empty_lines: true,
|
|
116
|
+
trim: true,
|
|
117
|
+
});
|
|
118
|
+
ctx.logger.debug(`Parsed ${records.length} usage records from CSV`);
|
|
119
|
+
return records;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
throw new Error(`Failed to download/parse CSV: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
convertCsvToMetricValues(records) {
|
|
126
|
+
const metricValues = [];
|
|
127
|
+
for (const record of records) {
|
|
128
|
+
const computedAt = (0, faros_airbyte_cdk_1.toDate)(record.JOB_RUN_DATE);
|
|
129
|
+
if (!computedAt) {
|
|
130
|
+
continue; // Skip records with invalid dates
|
|
131
|
+
}
|
|
132
|
+
// Create a metric value for each credit type
|
|
133
|
+
for (const creditType of CREDIT_TYPES) {
|
|
134
|
+
const value = record[creditType];
|
|
135
|
+
if (value && !isNaN(parseFloat(value)) && isFinite(parseFloat(value))) {
|
|
136
|
+
metricValues.push({
|
|
137
|
+
model: 'faros_MetricValue',
|
|
138
|
+
record: {
|
|
139
|
+
uid: `${record.JOB_ID}_${creditType.toLowerCase()}`,
|
|
140
|
+
value: value,
|
|
141
|
+
computedAt: computedAt.toISOString(),
|
|
142
|
+
definition: { uid: Usage.METRIC_DEFINITION_UID },
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return metricValues;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.Usage = Usage;
|
|
152
|
+
Usage.METRIC_DEFINITION_UID = 'circleci_job_usage';
|
|
153
|
+
Usage.metricDefinitionWritten = false;
|
|
154
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/converters/circleci/usage.ts"],"names":[],"mappings":"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"}
|