Skip to content

Commit

Permalink
add sonatype load
Browse files Browse the repository at this point in the history
  • Loading branch information
leordev committed Jun 2, 2024
1 parent c67f93a commit 964cdbc
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 25 deletions.
37 changes: 32 additions & 5 deletions metrics-collector/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { hideBin } from "yargs/helpers";

import { collectGhMetrics } from "./gh-metrics";
import { collectNpmMetrics, saveNpmMetrics } from "./npm-metrics";
import { collectSonatypeMetrics } from "./sonatype-metrics";
import {
collectSonatypeMetrics,
saveSonatypeMetrics,
} from "./sonatype-metrics";
import { getYesterdayDate } from "./utils";

const isLocalPersistence = process.env.PERSIST_LOCAL_FILES === "true";
Expand Down Expand Up @@ -70,7 +73,19 @@ async function main() {

const collectSonatype = argv["collect-sonatype"];
if (collectSonatype) {
await collectSonatypeMetrics(isLocalPersistence);
console.info(
`\n\n============\n\n>>> Collecting metrics for Maven Sonatype...`
);
if (initialLoadFromDate) {
await initialLoad(
initialLoadFromDate,
metricDate,
collectSonatypeMetrics,
true
);
} else {
await collectSonatypeMetrics(metricDateStr);
}
}

const collectGh = argv["collect-gh"];
Expand All @@ -81,22 +96,34 @@ async function main() {
const localCollection = !collectGh && !collectNpm && !collectSonatype;
if (localCollection) {
await saveNpmMetrics();
await saveSonatypeMetrics();
// await saveGhMetrics();
// await saveSonatypeMetrics();
}
}

async function initialLoad(
initialLoadFromDate: Date,
initialLoadToDate: Date,
collectMetrics: (metricDate: string) => Promise<void>
collectMetrics: (metricDate: string) => Promise<void>,
monthlyInterval = false
) {
let date = initialLoadFromDate;
if (monthlyInterval) {
// Change the date to the first day of the month
date.setDate(0);
}

while (date <= initialLoadToDate) {
const dateStr = date.toISOString().split("T")[0];
console.log(`\n\n>>> Collecting metrics for date: ${dateStr}`);
await collectMetrics(dateStr);
date.setDate(date.getDate() + 1);

if (monthlyInterval) {
// Move to the next month (JS will handle year change automatically)
date.setMonth(date.getMonth() + 1);
} else {
date.setDate(date.getDate() + 1);
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion metrics-collector/src/npm-metrics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from "fs";
import * as path from "path";
import { createObjectCsvWriter } from "csv-writer";
import { getYesterdayDate, readJsonFile, writeJsonFile } from "./utils";
import { readJsonFile, writeJsonFile } from "./utils";
import { postMetric } from "./post-metric";

// Define the npm packages to collect metrics for
Expand All @@ -10,7 +10,13 @@ const npmPackages = [
"@web5/common",
"@web5/credentials",
"@web5/crypto",
"@web5/crypto-aws-kms",
"@web5/dids",
"@web5/api",
"@web5/agent",
"@web5/identity-agent",
"@web5/proxy-agent",
"@web5/user-agent",
"@tbdex/protocol",
"@tbdex/http-client",
"@tbdex/http-server",
Expand Down
7 changes: 5 additions & 2 deletions metrics-collector/src/post-metric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ export const postMetric = async (
});

if (!response.ok) {
if (response.body) {
const error = await response.json();
console.error("Errored response body:", { error });
}
throw new Error(`Error posting metric: ${response.statusText}`);
}

const data = await response.json();
console.log("Metric posted successfully:", JSON.stringify(payload));
} catch (error) {
console.error("Error posting metric:", error);
console.error("Error posting metric:", error, JSON.stringify(error));
}
};
2 changes: 1 addition & 1 deletion metrics-collector/src/service-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ if (!process.env.DB_SKIP_INIT) {
// Collect Metrics Endpoint
app.post("/api/v1/metrics", async (req: any, res: any) => {
const { metricName, value, labels, timestamp } = req.body;
if (!metricName || !value) {
if (!metricName || value == undefined) {
return res
.status(400)
.send({ error: "Missing required fields: metricName and value" });
Expand Down
88 changes: 72 additions & 16 deletions metrics-collector/src/sonatype-metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as fs from "fs";
import * as path from "path";
import { createObjectCsvWriter } from "csv-writer";
import { readJsonFile, writeJsonFile } from "./utils";
import { postMetric } from "./post-metric";

// Define the group id to collect metrics for
const groupId = "xyz.block";
Expand All @@ -15,7 +16,54 @@ const requestHeaders: Record<string, string> = {
const sonatypeCentralStatsUrl =
"https://s01.oss.sonatype.org/service/local/stats";

async function collectSonatypeMetrics(isLocalPersistence: boolean = false) {
export async function collectSonatypeMetrics(metricDate: string) {
initAuth();

const projectId = await getProjectId(groupId);
const artifacts = await getArtifacts(projectId, groupId);

for (const artifact of artifacts) {
const [rawDownloads, uniqueIPs] = await Promise.all([
getArtifactStats(projectId, groupId, artifact, "raw", metricDate),
getArtifactStats(projectId, groupId, artifact, "ip", metricDate),
]);

await postSonatypeMavenMetrics({
artifact,
metricDate: new Date(metricDate),
rawDownloads: rawDownloads.total,
uniqueIPs: uniqueIPs.total,
});
}
}

async function postSonatypeMavenMetrics(metric: {
artifact: string;
metricDate: Date;
rawDownloads: number;
uniqueIPs: number;
}) {
console.info("posting sonatype metric", { metric });
const labels = {
artifact: metric.artifact,
};

await postMetric(
"sonatype_central_stats_downloads",
metric.rawDownloads,
labels,
metric.metricDate
);

await postMetric(
"sonatype_central_stats_unique_ips_downloads",
metric.uniqueIPs,
labels,
metric.metricDate
);
}

export async function saveSonatypeMetrics() {
initAuth();

const timestamp = new Date().toISOString();
Expand All @@ -39,20 +87,18 @@ async function collectSonatypeMetrics(isLocalPersistence: boolean = false) {

console.info("Sonatype metrics collected successfully", { metrics });

if (isLocalPersistence) {
const sonatypeMetrics = readJsonFile(dataFilePath);
for (const metric of metrics) {
if (!sonatypeMetrics[metric.artifact]) {
sonatypeMetrics[metric.artifact] = [];
}
sonatypeMetrics[metric.artifact].push(metric);
const sonatypeMetrics = readJsonFile(dataFilePath);
for (const metric of metrics) {
if (!sonatypeMetrics[metric.artifact]) {
sonatypeMetrics[metric.artifact] = [];
}
writeJsonFile(dataFilePath, sonatypeMetrics);
await writeMetricsToCsv(csvFilePath, sonatypeMetrics);
console.log(
"Sonatype metrics have been successfully saved to sonatype_metrics.json and sonatype_metrics.csv"
);
sonatypeMetrics[metric.artifact].push(metric);
}
writeJsonFile(dataFilePath, sonatypeMetrics);
await writeMetricsToCsv(csvFilePath, sonatypeMetrics);
console.log(
"Sonatype metrics have been successfully saved to sonatype_metrics.json and sonatype_metrics.csv"
);

return metrics;
}
Expand Down Expand Up @@ -114,9 +160,12 @@ async function getArtifactStats(
projectId: string,
groupId: string,
artifactId: string,
type: string
type: string,
fromDate?: string
): Promise<{ total: number }> {
const from = getLastMonthDate();
const from = fromDate
? convertDateToLastYearMonth(fromDate)
: getLastMonthDate();
console.info(
`Fetching ${type} stats for artifact ${artifactId} from ${from}...`
);
Expand Down Expand Up @@ -181,4 +230,11 @@ function getLastMonthDate() {
return `${lastMonthYear}${String(lastMonth).padStart(2, "0")}`;
}

export { collectSonatypeMetrics };
// function to convert YYYY-MM-DD to YYYYMM
function convertDateToLastYearMonth(date: string) {
const lastMonth = new Date(date);
// reduce 1 month, JS will automatically adjust the year if needed
lastMonth.setMonth(lastMonth.getMonth() - 1);
const [year, month] = lastMonth.toISOString().split("T")[0].split("-");
return `${year}${month}`;
}

0 comments on commit 964cdbc

Please sign in to comment.