Skip to content
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

feat: add asyncapi file birth timestamp in metrics collection. #1304

Merged
merged 25 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ spec-examples.zip
# Coverage for testing

coverage
.asyncapi-analytics
10 changes: 9 additions & 1 deletion src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MetadataFromDocument, MetricMetadata, NewRelicSink, Recorder, Sink, Std
import { Parser } from '@asyncapi/parser';
import { Specification } from 'models/SpecificationFile';
import { join, resolve } from 'path';
import { existsSync } from 'fs-extra';
import { existsSync, statSync } from 'fs-extra';
Copy link
Member

Choose a reason for hiding this comment

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

Why not using the asynchronous versions of these functions? 🤔 You can easily make setSource an async function and then it would be easy to call await stat() instead.

Copy link
Member

Choose a reason for hiding this comment

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

Working fine with: const stats = await fPromises.stat(specFilePath);
Don't know if there is any better alternative to make setSource an async function.

Copy link
Member Author

Choose a reason for hiding this comment

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

@peter-rr I don't think there is any. we either have to use promises and await it. or use Sync functions. which I guess the first option is a lot better.

import { promises as fPromises } from 'fs';
import { v4 as uuidv4 } from 'uuid';

Expand All @@ -20,6 +20,7 @@ export default abstract class extends Command {
parser = new Parser();
metricsMetadata: MetricMetadata = {};
specFile: Specification | undefined;
specFilePath: string | undefined;

async init(): Promise<void> {
await super.init();
Expand Down Expand Up @@ -69,6 +70,7 @@ export default abstract class extends Command {

async recordActionMetric(recordFunc: (recorder: Recorder) => Promise<void>) {
try {
this.setSource();
KhudaDad414 marked this conversation as resolved.
Show resolved Hide resolved
await recordFunc(await this.recorder);
await (await this.recorder).flush();
} catch (e: any) {
Expand All @@ -78,6 +80,12 @@ export default abstract class extends Command {
}
}

setSource() {
if (this.specFilePath) {
const stats = statSync(this.specFilePath);
this.metricsMetadata['file_creation_timestamp'] = stats.birthtimeMs;
}
}
async finally(error: Error | undefined): Promise<any> {
await super.finally(error);
this.metricsMetadata['success'] = error === undefined;
Expand Down
4 changes: 2 additions & 2 deletions src/commands/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class Bundle extends Command {

this.metricsMetadata.files = AsyncAPIFiles.length;

if (flags.base) {baseFile = (await load(flags.base)).text();}
if (flags.base) {baseFile = (await load(this,flags.base)).text();}

const fileContents = AsyncAPIFiles.map((file) => file.text());

Expand Down Expand Up @@ -90,7 +90,7 @@ export default class Bundle extends Command {
async loadFiles(filepaths: string[]): Promise<Specification[]> {
const files = [];
for (const filepath of filepaths) {
const file = await load(filepath);
const file = await load(this,filepath);
files.push(file);
}
return files;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class Convert extends Command {

try {
// LOAD FILE
this.specFile = await load(filePath);
this.specFile = await load(this,filePath);
this.metricsMetadata.to_version = flags['target-version'];

// CONVERSION
Expand Down
4 changes: 2 additions & 2 deletions src/commands/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export default class Diff extends Command {
markdownSubtype = setDefaultMarkdownSubtype(outputFormat, markdownSubtype);

try {
firstDocument = await load(firstDocumentPath);
firstDocument = await load(this,firstDocumentPath);

if (firstDocument.isAsyncAPI3()) {
this.error('Diff command does not support AsyncAPI v3 yet which was your first document, please checkout https://github.com/asyncapi/diff/issues/154');
Expand All @@ -111,7 +111,7 @@ export default class Diff extends Command {
}

try {
secondDocument = await load(secondDocumentPath);
secondDocument = await load(this,secondDocumentPath);

if (secondDocument.isAsyncAPI3()) {
this.error('Diff command does not support AsyncAPI v3 yet which was your second document, please checkout https://github.com/asyncapi/diff/issues/154');
Expand Down
6 changes: 3 additions & 3 deletions src/commands/generate/fromTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export default class Template extends Command {
mapBaseUrlToFolder: parsedFlags.mapBaseUrlToFolder,
disabledHooks: parsedFlags.disableHooks,
};
const asyncapiInput = (await load(asyncapi)) || (await load());
const asyncapiInput = (await load(this,asyncapi)) || (await load(this));

this.specFile = asyncapiInput;
this.metricsMetadata.template = template;
Expand Down Expand Up @@ -207,7 +207,7 @@ export default class Template extends Command {
private async generate(asyncapi: string | undefined, template: string, output: string, options: any, genOption: any) {
let specification: Specification;
try {
specification = await load(asyncapi);
specification = await load(this,asyncapi);
} catch (err: any) {
return this.error(
new ValidationError({
Expand All @@ -231,7 +231,7 @@ export default class Template extends Command {
}

private async runWatchMode(asyncapi: string | undefined, template: string, output: string, watchHandler: ReturnType<typeof this.watcherHandler>) {
const specification = await load(asyncapi);
const specification = await load(this,asyncapi);

const watchDir = path.resolve(template);
const outputPath = path.resolve(watchDir, output);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/generate/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export default class Models extends Command {
const { args, flags } = await this.parse(Models);
const { tsModelType, tsEnumType, tsIncludeComments, tsModuleSystem, tsExportType, tsJsonBinPack, tsMarshalling, tsExampleInstance, namespace, csharpAutoImplement, csharpArrayType, csharpNewtonsoft, csharpHashcode, csharpEqual, csharpSystemJson, packageName, javaIncludeComments, javaJackson, javaConstraints, output } = flags;
const { language, file } = args;
const inputFile = (await load(file)) || (await load());
const inputFile = (await load(this,file)) || (await load(this));
if (inputFile.isAsyncAPI3()) {
this.error('Generate Models command does not support AsyncAPI v3 yet, please checkout https://github.com/asyncapi/modelina/issues/1376');
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/new/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export default class NewFile extends Command {
}
await writeFile(fileNameToWriteToDisk, asyncApiFile, { encoding: 'utf8' });
console.log(`Created file ${fileNameToWriteToDisk}...`);
this.specFile = await load(fileNameToWriteToDisk);
this.specFile = await load(this,fileNameToWriteToDisk);
this.metricsMetadata.selected_template = selectedTemplate;
}
}
2 changes: 1 addition & 1 deletion src/commands/new/glee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export default class NewGlee extends Command {

try {
console.log(file);
const asyncapiInput = (await load(file)) || (await load());
const asyncapiInput = (await load(this,file)) || (await load(this));
console.log(asyncapiInput);

const serversObject = asyncapiInput.toJson()?.servers;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/optimize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class Optimize extends Command {
const filePath = args['spec-file'];

try {
this.specFile = await load(filePath);
this.specFile = await load(this,filePath);
} catch (err) {
this.error(
new ValidationError({
Expand Down
2 changes: 1 addition & 1 deletion src/commands/start/studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class StartStudio extends Command {

async run() {
const { flags } = await this.parse(StartStudio);
const filePath = flags.file || (await load()).getFilePath();
const filePath = flags.file || (await load(this)).getFilePath();
const port = flags.port;

startStudio(filePath as string, port);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class Validate extends Command {
const filePath = args['spec-file'];
const watchMode = flags.watch;

this.specFile = await load(filePath);
this.specFile = await load(this,filePath);
if (watchMode) {
specWatcher({ spec: this.specFile, handler: this, handlerName: 'validate' });
}
Expand Down
4 changes: 3 additions & 1 deletion src/models/SpecificationFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import yaml from 'js-yaml';
import { loadContext } from './Context';
import { ErrorLoadingSpec } from '../errors/specification-file';
import { MissingContextFileError } from '../errors/context-error';
import type Command from 'base';

const { readFile, lstat } = fs;
const allowedFileNames: string[] = [
Expand Down Expand Up @@ -121,7 +122,7 @@ interface LoadType {
}

/* eslint-disable sonarjs/cognitive-complexity */
export async function load(filePathOrContextName?: string, loadType?: LoadType): Promise<Specification> { // NOSONAR
export async function load(command?: Command, filePathOrContextName?: string, loadType?: LoadType): Promise<Specification> { // NOSONAR
if (filePathOrContextName) {
if (loadType?.file) { return Specification.fromFile(filePathOrContextName); }
if (loadType?.context) { return loadFromContext(filePathOrContextName); }
Expand All @@ -136,6 +137,7 @@ export async function load(filePathOrContextName?: string, loadType?: LoadType):
return Specification.fromURL(filePathOrContextName);
}
await fileExists(filePathOrContextName);
if (command) {command.specFilePath = filePathOrContextName;}
KhudaDad414 marked this conversation as resolved.
Show resolved Hide resolved
return Specification.fromFile(filePathOrContextName);
}

Expand Down
Loading