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

Moved query of log file content to GraphQL #536

Merged
merged 11 commits into from
Oct 23, 2023
Merged
2 changes: 0 additions & 2 deletions .github/workflows/translations-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ on:
schedule:
- cron: '00 3 * * 1'



jobs:
crowdin-translations-to-pr:
name: Create a PR with the latest translations from Crowdin
Expand Down
13 changes: 7 additions & 6 deletions crowdin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ base_path: "."

preserve_hierarchy: true

files: [
{
"source": "/src/i18n/locales/en/messages.json",
"translation": "/src/i18n/locales/%two_letters_code%/%original_file_name%",
}
]
files:
[
{
'source': '/src/i18n/locales/en/messages.json',
'translation': '/src/i18n/locales/%two_letters_code%/%original_file_name%',
},
]
155 changes: 155 additions & 0 deletions graphql.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,128 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "Int",
"description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "JSONObject",
"description": "JSON object",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "LogEntry",
"description": null,
"fields": [
{
"name": "context",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "JSONObject",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "level",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "message",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "timestamp",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "LogFile",
"description": null,
"fields": [
{
"name": "content",
"description": null,
"args": [],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "LogEntry",
"ofType": null
}
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "LuaScript",
Expand Down Expand Up @@ -2071,6 +2193,39 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "logFile",
"description": null,
"args": [
{
"name": "numberOfLines",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"defaultValue": "500",
"isDeprecated": false,
"deprecationReason": null
}
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "LogFile",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "luaScript",
"description": null,
Expand Down
4 changes: 4 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import MulticastDnsService from './src/services/MulticastDns';
import MulticastDnsMonitorResolver from './src/graphql/resolvers/MulticastDnsMonitor.resolver';
import LuaService from './src/services/Lua';
import LuaResolver from './src/graphql/resolvers/Lua.resolver';
import LogFileService from './src/services/LogFile';
import LogFileResolver from './src/graphql/resolvers/LogFile.resolver';
import MulticastDnsSimulatorService from './src/services/MulticastDns/MulticastDnsSimulator';
import MulticastDnsNotificationsService from './src/services/MulticastDnsNotificationsService';
import TargetsLoader from './src/services/TargetsLoader';
Expand Down Expand Up @@ -170,6 +172,7 @@ export default class ApiServer {
);

Container.set(LuaService, new LuaService(logger));
Container.set(LogFileService, new LogFileService(logger));
}

async start(
Expand Down Expand Up @@ -202,6 +205,7 @@ export default class ApiServer {
SerialMonitorResolver,
MulticastDnsMonitorResolver,
LuaResolver,
LogFileResolver,
],
container: Container,
pubSub: Container.get<PubSub>(PubSubToken),
Expand Down
11 changes: 11 additions & 0 deletions src/api/src/graphql/args/LogFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ArgsType, Field, Int } from 'type-graphql';

@ArgsType()
export default class LogFileArgs {
@Field(() => Int)
numberOfLines: number;

constructor() {
this.numberOfLines = 500;
}
}
17 changes: 17 additions & 0 deletions src/api/src/graphql/resolvers/LogFile.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Args, Query, Resolver } from 'type-graphql';
import { Service } from 'typedi';
import LogFileService from '../../services/LogFile';
import LogFile from '../../models/LogFile';
import LogFileArgs from '../args/LogFile';

@Service()
@Resolver()
export default class LogFileResolver {
constructor(private logFileService: LogFileService) {}

@Query(() => LogFile)
async logFile(@Args() args: LogFileArgs): Promise<LogFile> {
const content = await this.logFileService.loadLogFile(args);
return { content };
}
}
36 changes: 36 additions & 0 deletions src/api/src/graphql/scalars/JSONObjectScalar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { GraphQLScalarType, Kind } from 'graphql';

const JSONObjectScalar = new GraphQLScalarType({
name: 'JSONObject',
description: 'JSON object',
parseValue: (value) => {
if (typeof value === 'object') {
return value;
}
if (typeof value === 'string') {
return JSON.parse(value);
}
return null;
},
serialize: (value) => {
if (typeof value === 'object') {
return value;
}
if (typeof value === 'string') {
return JSON.parse(value);
}
return null;
},
parseLiteral: (ast) => {
switch (ast.kind) {
case Kind.STRING:
return JSON.parse(ast.value);
case Kind.OBJECT:
throw new Error(`Not sure what to do with OBJECT for ObjectScalarType`);
default:
return null;
}
},
});

export default JSONObjectScalar;
14 changes: 13 additions & 1 deletion src/api/src/logger/WinstonLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Logger } from 'winston';
import { Service } from 'typedi';
import { LoggerService } from './index';
import { LoggerService, QueryOptions } from './index';

@Service()
export default class WinstonLoggerService implements LoggerService {
Expand Down Expand Up @@ -93,4 +93,16 @@ export default class WinstonLoggerService implements LoggerService {

return this.logger.verbose(message, { context });
}

public query(options?: QueryOptions): Promise<any> {
return new Promise((resolve, reject) => {
this.logger.query(options, (err: Error, result: any) => {
if (err) {
reject(err);
} else {
resolve(result.file);
}
});
});
}
}
9 changes: 8 additions & 1 deletion src/api/src/logger/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
export type QueryOptions = {
rows?: number;
order?: 'asc' | 'desc';
fields: string[];
};

/* eslint-disable @typescript-eslint/no-explicit-any */
export interface LoggerService {
log(message: any, context?: Record<string, unknown>): void;

Expand All @@ -10,4 +15,6 @@ export interface LoggerService {
debug?(message: any, context?: Record<string, unknown>): void;

verbose?(message: any, context?: Record<string, unknown>): void;

query(options?: QueryOptions): Promise<any>;
}
29 changes: 29 additions & 0 deletions src/api/src/models/LogEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Field, ObjectType } from 'type-graphql';
import JSONObjectScalar from '../graphql/scalars/JSONObjectScalar';

@ObjectType('LogEntry')
export default class LogEntry {
@Field()
level: string;
vbotnaru marked this conversation as resolved.
Show resolved Hide resolved

@Field()
message: string;

@Field()
timestamp: string;

@Field(() => JSONObjectScalar, { nullable: true })
context?: unknown;

constructor(
level: string,
message: string,
timestamp: string,
context?: unknown
) {
this.level = level;
this.message = message;
this.timestamp = timestamp;
this.context = context;
}
}
12 changes: 12 additions & 0 deletions src/api/src/models/LogFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Field, ObjectType } from 'type-graphql';
import LogEntry from './LogEntry';

@ObjectType('LogFile')
export default class LogFile {
@Field(() => [LogEntry], { nullable: true })
content: LogEntry[];

constructor(content: LogEntry[]) {
this.content = content;
}
}
Loading