Skip to content

Commit

Permalink
feat(log): add basic tracking
Browse files Browse the repository at this point in the history
Signed-off-by: Lukáš Janeček <[email protected]>
  • Loading branch information
Lukáš Janeček committed Dec 11, 2024
1 parent 0b46055 commit 158969b
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
72 changes: 72 additions & 0 deletions src/common/log.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Copyright 2024 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { ChangeSetType, Entity, ManyToOne, PrimaryKey, Property, ref, Ref } from '@mikro-orm/core';
import { User } from '@zilliz/milvus2-sdk-node';
import { requestContext } from '@fastify/request-context';

import { generatePrefixedObjectId } from '@/utils/id.js';
import { ProjectPrincipal } from '@/administration/entities/project-principal.entity';

@Entity()
export class Log {
@PrimaryKey({ fieldName: '_id' })
id = generatePrefixedObjectId('log');

@Property()
createdAt: Date = new Date();

@ManyToOne()
projectPrincipal?: Ref<ProjectPrincipal>;

@ManyToOne()
user?: Ref<User>;

@Property()
entity?: string;

@Property()
entityId?: string;

@Property()
type?: ChangeSetType;

@Property()
change?: any;

@Property()
additionalData: any;

constructor({ entity, entityId, type, change, additionalData }: LogInput) {
const user = requestContext.get('user');
if (user) {
this.user = ref(user);
}
const projectPrincipal = requestContext.get('projectPrincipal');
if (projectPrincipal) {
this.projectPrincipal = ref(projectPrincipal);
}
this.entity = entity;
this.entityId = entityId;
this.type = type;
this.change = change;
this.additionalData = additionalData;
}
}

export type LogInput = Partial<
Pick<Log, 'entity' | 'entityId' | 'type' | 'change' | 'additionalData'>
>;
85 changes: 85 additions & 0 deletions src/common/log.subscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { ChangeSetType, EventSubscriber, FlushEventArgs } from '@mikro-orm/core';

import { Log } from './log.entity';
import { BaseEntity } from './base.entity';

import { inJob, inSeeder } from '@/context';

const loggedEntities: { [key: string]: { types?: ChangeSetType[]; entities: string[] } } = {
Assistant: {
entities: ['project', 'agent']
},
Artifact: {
entities: ['project', 'thread', 'name']
},
Chat: {
types: [ChangeSetType.CREATE],
entities: ['artifact']
},
Message: {
entities: ['project']
},
Thread: {
entities: ['project']
},
Tool: {
entities: ['project', 'name']
},
VectorStore: {
entities: ['project', 'name']
},
VectorStoreFile: {
entities: ['project', 'file']
},
File: {
entities: ['project', 'filename']
},
Run: {
entities: ['project', 'assistant', 'status']
},
User: {
entities: ['email']
},
Organization: {
entities: ['name']
},
Project: {
entities: ['name', 'organization']
},
ApiKey: {
entities: ['project']
}
};

export class LogSubscriber implements EventSubscriber {
onFlush(args: FlushEventArgs): void | Promise<void> {
args.uow.getChangeSets().forEach((cs) => {
if (
loggedEntities[cs.name] &&
(loggedEntities[cs.name].types?.includes(cs.type) ?? true) &&
inSeeder() === false
) {
if (cs.type === ChangeSetType.DELETE && inJob()) return;

const log = new Log({
entity: cs.name,
entityId: cs.entity?.id,
type: cs.type,
change: cs.type === ChangeSetType.UPDATE ? cs.payload : undefined,
additionalData:
loggedEntities[cs.name].entities.reduce(
(acc, name) => ({
...acc,
[name]:
cs.entity[name].entity instanceof BaseEntity
? cs.entity[name].id
: cs.entity[name]
}),
{}
) ?? undefined
});
args.uow.computeChangeSet(log);
}
});
}
}
2 changes: 2 additions & 0 deletions src/mikro-orm.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { Migrator } from '@mikro-orm/migrations-mongodb';
import { SeedManager } from '@mikro-orm/seeder';

import { MONGODB_CA_CERT, MONGODB_DATABASE_NAME, MONGODB_URL } from './config.js';
import { LogSubscriber } from './common/log.subscriber.js';

if (process.env.NODE_ENV === 'production') {
process.env.MIKRO_ORM_NO_COLOR = 'true';
Expand Down Expand Up @@ -69,6 +70,7 @@ const config: Options<MongoDriver> = {
...createMongoTLSConfig()
},
extensions: [Migrator, SeedManager],
subscribers: [new LogSubscriber()],
migrations: {
path: './dist/migrations',
pathTs: './migrations',
Expand Down

0 comments on commit 158969b

Please sign in to comment.