Skip to content
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
6 changes: 6 additions & 0 deletions .changeset/tame-walls-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@nodesecure/scanner": minor
"@nodesecure/tarball": minor
---

feat: add path and file number for tarball stats
5 changes: 5 additions & 0 deletions workspaces/scanner/docs/logger.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ logger.on("stat", (stat: ApiStats) => {
console.log(`API call: ${stat.name}`);
console.log(`Duration: ${stat.executionTime}ms`);
console.log(`Start at: ${stat.startedAt}`);
// tarball specific stats
if(stat.tarball){
console.log(`path: ${stat.tarball.path}`);
console.log(`files count: ${stat.tarball.filesCount}`);
}
});

### depWalkerFinished
Expand Down
40 changes: 36 additions & 4 deletions workspaces/scanner/src/class/StatsCollector.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export type Options = {
isVerbose: boolean;
};

export type OnSuccess<T extends () => any> = (
res: Awaited<ReturnType<T>>,
stat: ApiStats
) => void;

export class StatsCollector {
#logger: EventEmitter<LoggerEventsMap>;
#dateProvider: DateProvider;
Expand All @@ -34,14 +39,26 @@ export class StatsCollector {
this.#isVerbose = options.isVerbose;
}

track<T extends () => any>(name: string, phase: string, fn: T): ReturnType<T> {
track<T extends () => any>(options: {
name: string;
phase: string;
fn: T;
onSuccess?: OnSuccess<T>;
}): ReturnType<T> {
const { name, phase, fn, onSuccess } = options;
const startedAt = this.#dateProvider.now();
try {
const result = fn();
if (result instanceof Promise) {
return result
.then((res: ReturnType<T>) => {
this.#addApiStatVerbose(name, startedAt, this.#calcExecutionTime(startedAt));
this.#addApiStatVerbose<T>({
name,
startedAt,
executionTime: this.#calcExecutionTime(startedAt),
result: res,
onSuccess
});

return res;
})
Expand All @@ -59,7 +76,13 @@ export class StatsCollector {
}) as ReturnType<T>;
}

this.#addApiStatVerbose(name, startedAt, this.#calcExecutionTime(startedAt));
this.#addApiStatVerbose({
name,
startedAt,
executionTime: this.#calcExecutionTime(startedAt),
result,
onSuccess
});

return result;
}
Expand All @@ -81,12 +104,21 @@ export class StatsCollector {
return this.#dateProvider.now() - startedAt;
}

#addApiStatVerbose(name: string, startedAt: number, executionTime: number) {
#addApiStatVerbose<T extends () => any>({ name, startedAt, executionTime, result, onSuccess }: {
name: string;
startedAt: number;
executionTime: number;
onSuccess?: OnSuccess<T>;
result: ReturnType<T>;
}) {
const stat = {
name,
startedAt,
executionTime
};
if (onSuccess) {
onSuccess(result as Awaited<ReturnType<T>>, stat);
}
this.#apiCalls.push(stat);
if (this.#isVerbose) {
this.#logger.emit("stat", stat);
Expand Down
37 changes: 25 additions & 12 deletions workspaces/scanner/src/class/TarballScanner.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,23 @@ export class TarballScanner {

const mama = await this.#extract(spec, registry);

const result = await this.#statsCollector.track(
`tarball.scanDirOrArchive ${spec}`,
"tarball-scan",
() => this.#workerPool!.scan({
const result = await this.#statsCollector.track({
name: `tarball.scanDirOrArchive ${spec}`,
phase: "tarball-scan",
fn: () => this.#workerPool!.scan({
location: mama.location!,
astAnalyserOptions: {
optionalWarnings: hasLocation
},
collectableTypes: this.#collectableTypes
})
);
}),
onSuccess: (result, stat) => {
stat.tarball = {
path: result.path,
filesCount: result.composition.files.length
};
}
});

this.#applyResult(ref, result);
this.#mergeCollectables(result.collectables);
Expand Down Expand Up @@ -149,16 +155,23 @@ export class TarballScanner {
})
);

await this.#statsCollector.track(
`tarball.scanDirOrArchive ${spec}`,
"tarball-scan",
() => scanDirOrArchive(mama, ref, {
await this.#statsCollector.track({
name: `tarball.scanDirOrArchive ${spec}`,
phase: "tarball-scan",
fn: () => scanDirOrArchive(mama, ref, {
astAnalyserOptions: {
optionalWarnings: hasLocation,
collectables: this.#collectables
}
})
);
}),
onSuccess: (_, stat) => {
stat.tarball = {
path: ref.path,
filesCount: ref.composition.files.length
};
delete ref.path;
}
});
}

async #extract(
Expand Down
59 changes: 32 additions & 27 deletions workspaces/scanner/src/depWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,14 @@ export async function depWalker(

const pacoteProvider: PacoteProvider = {
async extract(spec, dest, opts): Promise<void> {
await statsCollector.track(
`pacote.extract ${spec}`,
"tarball-scan",
() => pacote.extract(spec, dest, {
await statsCollector.track({
name: `pacote.extract ${spec}`,
phase: "tarball-scan",
fn: () => pacote.extract(spec, dest, {
...opts,
...pacoteScopedConfig
})
);
});
}
};

Expand Down Expand Up @@ -191,32 +191,37 @@ export async function depWalker(
registry,
providers: {
pacote: {
manifest: (spec, opts) => statsCollector.track(`pacote.manifest ${spec}`, "tree-walk", () => pacote.manifest(spec,
{ ...opts, ...pacoteScopedConfig })),
packument: (spec, opts) => statsCollector.track(`pacote.packument ${spec}`,
"tree-walk",
() => pacote.packument(spec, { ...opts, ...pacoteScopedConfig }))
manifest: (spec, opts) => statsCollector.track({
name: `pacote.manifest ${spec}`,
phase: "tree-walk", fn: () => pacote.manifest(spec,
{ ...opts, ...pacoteScopedConfig })
}),
packument: (spec, opts) => statsCollector.track({
name: `pacote.packument ${spec}`,
phase: "tree-walk",
fn: () => pacote.packument(spec, { ...opts, ...pacoteScopedConfig })
})
}
}
});
const npmApiClient: NpmApiClient = {
packument: (name, opts) => statsCollector.track(
`npmRegistrySDK.packument ${name}`,
"metadata-fetch",
() => npmRegistrySDK.packument(name, opts)
),

packumentVersion: (name, version, opts) => statsCollector.track(
`npmRegistrySDK.packumentVersion ${name}@${version}`,
"metadata-fetch",
() => npmRegistrySDK.packumentVersion(name, version, opts)
),

org: (namespace) => statsCollector.track(
`npmRegistrySDK.org ${namespace}`,
"metadata-fetch",
() => npmRegistrySDK.org(namespace)
)
packument: (name, opts) => statsCollector.track({
name: `npmRegistrySDK.packument ${name}`,
phase: "metadata-fetch",
fn: () => npmRegistrySDK.packument(name, opts)
}),

packumentVersion: (name, version, opts) => statsCollector.track({
name: `npmRegistrySDK.packumentVersion ${name}@${version}`,
phase: "metadata-fetch",
fn: () => npmRegistrySDK.packumentVersion(name, version, opts)
}),

org: (namespace) => statsCollector.track({
name: `npmRegistrySDK.org ${namespace}`,
phase: "metadata-fetch",
fn: () => npmRegistrySDK.org(namespace)
})
};

logger
Expand Down
8 changes: 8 additions & 0 deletions workspaces/scanner/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { PackageModuleType } from "@nodesecure/mama";
import type { SpdxFileLicenseConformance } from "@nodesecure/conformance";
import type { IlluminatedContact } from "@nodesecure/contact";
import type { Contact, Dist } from "@nodesecure/npm-types";
import type { Path } from "@nodesecure/tarball";

export type Maintainer = Contact & {
/**
Expand Down Expand Up @@ -198,6 +199,13 @@ export type ApiStats = {
* Name of the api call
*/
name: string;
/**
* Tarball specific stats
*/
tarball?: {
path: Path;
filesCount: number;
};
};

export type Error = {
Expand Down
Loading
Loading