Refactor TelemetryService to Service across the application

- Replaced all instances of TelemetryService with Service in components, pages, and utilities.
- Updated related imports and state management to reflect the new Service model.
- Removed the TelemetryServices view and associated routes, as it is no longer needed.
- Adjusted breadcrumb and route mappings to remove references to Telemetry Services.
- Ensured that all relevant functionality, such as logs and metrics, now utilize the Service model.
This commit is contained in:
Nawaz Dhandala 2026-01-09 15:49:52 +00:00
parent 827e4c8b90
commit e7089e9e85
No known key found for this signature in database
GPG key ID: 96C5DCA24769DBCA
55 changed files with 437 additions and 2043 deletions

View file

@ -25,7 +25,7 @@ interface ExceptionResponse {
fingerprint: string;
}
interface TelemetryServiceResponse {
interface ServiceResponse {
id: string;
name: string;
description: string;
@ -33,7 +33,7 @@ interface TelemetryServiceResponse {
interface ExceptionDetailsResponse {
exception: ExceptionResponse;
telemetryService: TelemetryServiceResponse | null;
service: ServiceResponse | null;
message?: string;
}
@ -89,7 +89,7 @@ export interface ExceptionDetails {
exceptionType: string;
fingerprint: string;
};
telemetryService: {
service: {
id: string;
name: string;
description: string;
@ -223,19 +223,19 @@ export default class BackendAPI {
exceptionType: data.exception.exceptionType,
fingerprint: data.exception.fingerprint,
},
telemetryService: data.telemetryService
service: data.service
? {
id: data.telemetryService.id,
name: data.telemetryService.name,
description: data.telemetryService.description,
id: data.service.id,
name: data.service.name,
description: data.service.description,
}
: null,
};
}
// Get code repositories linked to a telemetry service
// Get code repositories linked to a service
public async getCodeRepositories(
telemetryServiceId: string,
serviceId: string,
): Promise<Array<CodeRepositoryInfo>> {
const url: URL = URL.fromURL(this.baseUrl).addRoute(
"/api/ai-agent-data/get-code-repositories",
@ -245,7 +245,7 @@ export default class BackendAPI {
url,
data: {
...AIAgentAPIRequest.getDefaultRequestBody(),
telemetryServiceId: telemetryServiceId,
serviceId: serviceId,
},
});
@ -261,7 +261,7 @@ export default class BackendAPI {
response.data as unknown as CodeRepositoriesResponse;
logger.debug(
`Got ${data.repositories.length} code repositories for telemetry service ${telemetryServiceId}`,
`Got ${data.repositories.length} code repositories for service ${serviceId}`,
);
return data.repositories.map((repo: CodeRepositoryResponse) => {

View file

@ -264,11 +264,6 @@ import ServiceMonitorService, {
Service as ServiceMonitorServiceType,
} from "Common/Server/Services/ServiceMonitorService";
import ServiceTelemetryService from "Common/Models/DatabaseModels/ServiceTelemetryService";
import ServiceTelemetryServiceService, {
Service as ServiceTelemetryServiceServiceType,
} from "Common/Server/Services/ServiceTelemetryServiceService";
import ServiceCodeRepository from "Common/Models/DatabaseModels/ServiceCodeRepository";
import ServiceCodeRepositoryService, {
Service as ServiceCodeRepositoryServiceType,
@ -329,9 +324,6 @@ import TeamComplianceSettingService, {
import TeamService, {
Service as TeamServiceType,
} from "Common/Server/Services/TeamService";
import TelemetryServiceService, {
Service as TelemetryServiceServiceType,
} from "Common/Server/Services/TelemetryServiceService";
import TelemetryUsageBillingService, {
Service as TelemetryUsageBillingServiceType,
} from "Common/Server/Services/TelemetryUsageBillingService";
@ -472,7 +464,6 @@ import Team from "Common/Models/DatabaseModels/Team";
import TeamMember from "Common/Models/DatabaseModels/TeamMember";
import TeamPermission from "Common/Models/DatabaseModels/TeamPermission";
import TeamComplianceSetting from "Common/Models/DatabaseModels/TeamComplianceSetting";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import TelemetryUsageBilling from "Common/Models/DatabaseModels/TelemetryUsageBilling";
import UserNotificationRule from "Common/Models/DatabaseModels/UserNotificationRule";
import UserNotificationSetting from "Common/Models/DatabaseModels/UserNotificationSetting";
@ -1012,14 +1003,6 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ServiceTelemetryService, ServiceTelemetryServiceServiceType>(
ServiceTelemetryService,
ServiceTelemetryServiceService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ServiceCodeRepository, ServiceCodeRepositoryServiceType>(
@ -1231,14 +1214,6 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<TelemetryService, TelemetryServiceServiceType>(
TelemetryService,
TelemetryServiceService,
).getRouter(),
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<WorkflowVariable, WorkflowVariableServiceType>(

View file

@ -138,7 +138,6 @@ import Team from "./Team";
import TeamMember from "./TeamMember";
import TeamPermission from "./TeamPermission";
import TeamComplianceSetting from "./TeamComplianceSetting";
import TelemetryService from "./TelemetryService";
import UsageBilling from "./TelemetryUsageBilling";
import User from "./User";
import UserSession from "./UserSession";
@ -159,7 +158,6 @@ import WorkflowLog from "./WorkflowLog";
import WorkflowVariables from "./WorkflowVariable";
import ServiceDependency from "./ServiceDependency";
import ServiceMonitor from "./ServiceMonitor";
import ServiceTelemetryService from "./ServiceTelemetryService";
import UserTotpAuth from "./UserTotpAuth";
import UserWebAuthn from "./UserWebAuthn";
@ -354,8 +352,6 @@ const AllModelTypes: Array<{
MonitorGroupOwnerUser,
MonitorGroupResource,
TelemetryService,
OnCallDutyPolicySchedule,
OnCallDutyPolicyScheduleLayer,
OnCallDutyPolicyScheduleLayerUser,
@ -377,7 +373,6 @@ const AllModelTypes: Array<{
ServiceOwnerUser,
ServiceDependency,
ServiceMonitor,
ServiceTelemetryService,
ServiceCodeRepository,
// Code Repository

View file

@ -27,7 +27,7 @@ import {
ManyToOne,
} from "typeorm";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import TelemetryService from "./TelemetryService";
import Service from "./Service";
@EnableDocumentation()
@TenantColumn("projectId")
@ -133,20 +133,20 @@ export default class MetricType extends BaseModel {
@TableColumn({
required: false,
type: TableColumnType.EntityArray,
modelType: TelemetryService,
title: "Telemetry Services",
modelType: Service,
title: "Services",
description: "List of services this metric is related to",
})
@ManyToMany(
() => {
return TelemetryService;
return Service;
},
{ eager: false },
)
@JoinTable({
name: "MetricTypeTelemetryService",
name: "MetricTypeService",
inverseJoinColumn: {
name: "telemetryServiceId",
name: "serviceId",
referencedColumnName: "_id",
},
joinColumn: {
@ -154,7 +154,7 @@ export default class MetricType extends BaseModel {
referencedColumnName: "_id",
},
})
public telemetryServices?: Array<TelemetryService> = undefined;
public services?: Array<Service> = undefined;
@ColumnAccessControl({
create: [

View file

@ -3,11 +3,9 @@ import Project from "./Project";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
import Color from "../../Types/Color";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
import AccessControlColumn from "../../Types/Database/AccessControlColumn";
import ColumnLength from "../../Types/Database/ColumnLength";
import ColumnType from "../../Types/Database/ColumnType";
@ -38,12 +36,6 @@ import {
@AccessControlColumn("labels")
@EnableDocumentation()
@TenantColumn("projectId")
@TableBillingAccessControl({
create: PlanType.Growth,
read: PlanType.Growth,
update: PlanType.Growth,
delete: PlanType.Growth,
})
@TableAccessControl({
create: [
Permission.ProjectOwner,
@ -519,4 +511,38 @@ export default class Service extends BaseModel {
type: ColumnType.JSON,
})
public techStack?: Array<TechStack> = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditService,
],
})
@TableColumn({
type: TableColumnType.Number,
title: "Retain Telemetry Data For Days",
description: "Number of days to retain telemetry data for this service.",
})
@Column({
type: ColumnType.Number,
nullable: true,
unique: false,
default: 15,
})
public retainTelemetryDataForDays?: number = undefined;
}

View file

@ -1,419 +0,0 @@
import Project from "./Project";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
import CanAccessIfCanReadOn from "../../Types/Database/CanAccessIfCanReadOn";
import ColumnType from "../../Types/Database/ColumnType";
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
import TableColumn from "../../Types/Database/TableColumn";
import TableColumnType from "../../Types/Database/TableColumnType";
import TableMetadata from "../../Types/Database/TableMetadata";
import TenantColumn from "../../Types/Database/TenantColumn";
import IconProp from "../../Types/Icon/IconProp";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
import Service from "./Service";
import TelemetryService from "./TelemetryService";
@CanAccessIfCanReadOn("serviceId")
@EnableDocumentation()
@TenantColumn("projectId")
@TableBillingAccessControl({
create: PlanType.Growth,
read: PlanType.Growth,
update: PlanType.Growth,
delete: PlanType.Growth,
})
@TableAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
delete: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.DeleteServiceTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditServiceTelemetryService,
],
})
@EnableWorkflow({
create: true,
delete: true,
update: true,
read: true,
})
@CrudApiEndpoint(new Route("/service-telemetry-service"))
@SlugifyColumn("name", "slug")
@TableMetadata({
tableName: "ServiceTelemetryService",
singularName: "Service Telemetry Service",
pluralName: "Service Telemetry Services",
icon: IconProp.SquareStack,
tableDescription: "List of telemetry service - service relationship.",
})
@Entity({
name: "ServiceTelemetryService",
})
export default class ServiceTelemetryService extends BaseModel {
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "projectId",
type: TableColumnType.Entity,
modelType: Project,
title: "Project",
description: "Relation to Project Resource in which this object belongs",
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
})
@ManyToOne(
() => {
return Project;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "projectId" })
public project?: Project = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Project ID",
description: "ID of your OneUptime Project in which this object belongs",
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "serviceId",
type: TableColumnType.Entity,
modelType: Service,
title: "Service",
description: "Relation to Service Resource in which this object belongs",
example: "f6a7b8c9-d0e1-2345-fa67-bc89de012345",
})
@ManyToOne(
() => {
return Service;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "serviceId" })
public service?: Service = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Service ID",
description: "ID of your OneUptime Service in which this object belongs",
example: "f6a7b8c9-d0e1-2345-fa67-bc89de012345",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public serviceId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "telemetryServiceId",
type: TableColumnType.Entity,
modelType: TelemetryService,
title: "TelemetryService",
description: "Relation to TelemetryService in which this object belongs",
example: "c9d0e1f2-a3b4-5678-cd90-ef12ab345678",
})
@ManyToOne(
() => {
return TelemetryService;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "telemetryServiceId" })
public telemetryService?: TelemetryService = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "TelemetryService ID",
description: "ID of your TelemetryServicein which this object belongs",
example: "c9d0e1f2-a3b4-5678-cd90-ef12ab345678",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public telemetryServiceId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "createdByUserId",
type: TableColumnType.Entity,
modelType: User,
title: "Created by User",
description:
"Relation to User who created this object (if this object was created by a User)",
example: "c3d4e5f6-a7b8-9012-cd34-ef56ab789012",
})
@ManyToOne(
() => {
return User;
},
{
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "createdByUserId" })
public createdByUser?: User = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateServiceTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Created by User ID",
description:
"User ID who created this object (if this object was created by a User)",
example: "c3d4e5f6-a7b8-9012-cd34-ef56ab789012",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "deletedByUserId",
type: TableColumnType.Entity,
title: "Deleted by User",
modelType: User,
description:
"Relation to User who deleted this object (if this object was deleted by a User)",
example: "d4e5f6a7-b8c9-0123-de45-fa67bc890123",
})
@ManyToOne(
() => {
return User;
},
{
cascade: false,
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "deletedByUserId" })
public deletedByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadServiceTelemetryService,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Deleted by User ID",
description:
"User ID who deleted this object (if this object was deleted by a User)",
example: "d4e5f6a7-b8c9-0123-de45-fa67bc890123",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public deletedByUserId?: ObjectID = undefined;
}

View file

@ -17,7 +17,7 @@ import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
import DatabaseBaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import TelemetryService from "./TelemetryService";
import Service from "./Service";
@EnableDocumentation()
@TenantColumn("projectId")
@ -142,17 +142,16 @@ export default class TelemetryException extends DatabaseBaseModel {
],
})
@TableColumn({
manyToOneRelationColumn: "telemetryServiceId",
manyToOneRelationColumn: "serviceId",
type: TableColumnType.Entity,
modelType: TelemetryService,
title: "Telemetry Service",
description:
"Relation to Telemetry Service Resource in which this object belongs",
modelType: Service,
title: "Service",
description: "Relation to Service Resource in which this object belongs",
example: "d4e5f6a7-b8c9-0123-def1-234567890123",
})
@ManyToOne(
() => {
return TelemetryService;
return Service;
},
{
eager: false,
@ -161,8 +160,8 @@ export default class TelemetryException extends DatabaseBaseModel {
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "telemetryServiceId" })
public telemetryService?: TelemetryService = undefined;
@JoinColumn({ name: "serviceId" })
public service?: Service = undefined;
@ColumnAccessControl({
create: [
@ -186,9 +185,8 @@ export default class TelemetryException extends DatabaseBaseModel {
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
title: "Telemetry Service ID",
description:
"ID of your Telemetry Service resource where this object belongs",
title: "Service ID",
description: "ID of your Service resource where this object belongs",
example: "d4e5f6a7-b8c9-0123-def1-234567890123",
})
@Column({
@ -196,7 +194,7 @@ export default class TelemetryException extends DatabaseBaseModel {
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public telemetryServiceId?: ObjectID = undefined;
public serviceId?: ObjectID = undefined;
@ColumnAccessControl({
create: [

View file

@ -1,529 +0,0 @@
import Label from "./Label";
import Project from "./Project";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
import Color from "../../Types/Color";
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
import AccessControlColumn from "../../Types/Database/AccessControlColumn";
import ColumnLength from "../../Types/Database/ColumnLength";
import ColumnType from "../../Types/Database/ColumnType";
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
import ColorField from "../../Types/Database/ColorField";
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
import TableColumn from "../../Types/Database/TableColumn";
import TableColumnType from "../../Types/Database/TableColumnType";
import TableMetadata from "../../Types/Database/TableMetadata";
import TenantColumn from "../../Types/Database/TenantColumn";
import UniqueColumnBy from "../../Types/Database/UniqueColumnBy";
import IconProp from "../../Types/Icon/IconProp";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import {
Column,
Entity,
Index,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
} from "typeorm";
@AccessControlColumn("labels")
@EnableDocumentation()
@TenantColumn("projectId")
@TableAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
delete: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.DeleteTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditTelemetryService,
],
})
@EnableWorkflow({
create: true,
delete: true,
update: true,
read: true,
})
@CrudApiEndpoint(new Route("/telemetry-service"))
@SlugifyColumn("name", "slug")
@TableMetadata({
tableName: "TelemetryService",
singularName: "Telemetry Service",
pluralName: "Telemetry Services",
icon: IconProp.SquareStack,
tableDescription:
"Telemetry Services are the services that you can use to monitor your services. You can create multiple Telemetry Services and use them to monitor your services.",
})
@Entity({
name: "TelemetryService",
})
export default class TelemetryService extends BaseModel {
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "projectId",
type: TableColumnType.Entity,
modelType: Project,
title: "Project",
description: "Relation to Project Resource in which this object belongs",
})
@ManyToOne(
() => {
return Project;
},
{
eager: false,
nullable: true,
onDelete: "CASCADE",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "projectId" })
public project?: Project = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
canReadOnRelationQuery: true,
title: "Project ID",
description: "ID of your OneUptime Project in which this object belongs",
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditTelemetryService,
],
})
@TableColumn({
required: true,
type: TableColumnType.ShortText,
canReadOnRelationQuery: true,
title: "Name",
description: "Any friendly name of this object",
example: "Payment API Service",
})
@Column({
nullable: false,
type: ColumnType.ShortText,
length: ColumnLength.ShortText,
})
@UniqueColumnBy("projectId")
public name?: string = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [],
})
@TableColumn({
required: true,
unique: true,
type: TableColumnType.Slug,
computed: true,
title: "Slug",
description: "Friendly globally unique name for your object",
})
@Column({
nullable: false,
type: ColumnType.Slug,
length: ColumnLength.Slug,
})
public slug?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditTelemetryService,
],
})
@TableColumn({
required: false,
type: TableColumnType.LongText,
title: "Description",
description: "Friendly description that will help you remember",
example: "Telemetry and monitoring for the payment processing API service",
})
@Column({
nullable: true,
type: ColumnType.LongText,
length: ColumnLength.LongText,
})
public description?: string = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "createdByUserId",
type: TableColumnType.Entity,
modelType: User,
title: "Created by User",
description:
"Relation to User who created this object (if this object was created by a User)",
})
@ManyToOne(
() => {
return User;
},
{
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "createdByUserId" })
public createdByUser?: User = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Created by User ID",
description:
"User ID who created this object (if this object was created by a User)",
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [],
})
@TableColumn({
manyToOneRelationColumn: "deletedByUserId",
type: TableColumnType.Entity,
title: "Deleted by User",
modelType: User,
description:
"Relation to User who deleted this object (if this object was deleted by a User)",
})
@ManyToOne(
() => {
return User;
},
{
cascade: false,
eager: false,
nullable: true,
onDelete: "SET NULL",
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "deletedByUserId" })
public deletedByUser?: User = undefined;
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [],
})
@TableColumn({
type: TableColumnType.ObjectID,
title: "Deleted by User ID",
description:
"User ID who deleted this object (if this object was deleted by a User)",
example: "b2c3d4e5-f6a7-8901-bcde-f2345678901a",
})
@Column({
type: ColumnType.ObjectID,
nullable: true,
transformer: ObjectID.getDatabaseTransformer(),
})
public deletedByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditTelemetryService,
],
})
@TableColumn({
required: false,
type: TableColumnType.EntityArray,
modelType: Label,
title: "Labels",
description:
"Relation to Labels Array where this object is categorized in.",
})
@ManyToMany(
() => {
return Label;
},
{ eager: false },
)
@JoinTable({
name: "TelemetryServiceLabel",
inverseJoinColumn: {
name: "labelId",
referencedColumnName: "_id",
},
joinColumn: {
name: "telemetryServiceId",
referencedColumnName: "_id",
},
})
public labels?: Array<Label> = undefined;
// This field is deprecared and is no longer used.
@ColumnAccessControl({
create: [],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditTelemetryService,
],
})
@Index()
@TableColumn({
type: TableColumnType.ObjectID,
isDefaultValueColumn: false,
computed: true,
title: "Service Token",
description: "Service Token for this telemetry service",
example: "e5f6a7b8-c9d0-1234-efab-56789012cdef",
})
@Column({
type: ColumnType.ObjectID,
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public telemetryServiceToken?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditTelemetryService,
],
})
@TableColumn({
type: TableColumnType.Number,
title: "Retain Telemetry Data For Days",
description: "Number of days to retain telemetry data for this service.",
})
@Column({
type: ColumnType.Number,
nullable: true,
unique: false,
default: 15,
})
public retainTelemetryDataForDays?: number = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CreateTelemetryService,
],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ProjectMember,
Permission.ReadTelemetryService,
],
update: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditTelemetryService,
],
})
@ColorField()
@TableColumn({
type: TableColumnType.Color,
title: "Service Color",
description: "Color for this telemetry service",
canReadOnRelationQuery: true,
})
@Column({
type: ColumnType.Color,
nullable: true,
unique: false,
transformer: Color.getDatabaseTransformer(),
})
public serviceColor?: Color = undefined;
}

View file

@ -1,5 +1,5 @@
import Project from "./Project";
import TelemetryService from "./TelemetryService";
import Service from "./Service";
import User from "./User";
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
import Route from "../../Types/API/Route";
@ -256,17 +256,16 @@ export default class TelemetryUsageBilling extends BaseModel {
update: [],
})
@TableColumn({
manyToOneRelationColumn: "telemetryServiceId",
manyToOneRelationColumn: "serviceId",
type: TableColumnType.Entity,
modelType: TelemetryService,
title: "Telemetry Service",
description:
"Relation to Telemetry Service Resource in which this object belongs",
modelType: Service,
title: "Service",
description: "Relation to Service Resource in which this object belongs",
example: "d4e5f6a7-b8c9-0123-def1-234567890123",
})
@ManyToOne(
() => {
return TelemetryService;
return Service;
},
{
eager: false,
@ -275,8 +274,8 @@ export default class TelemetryUsageBilling extends BaseModel {
orphanedRowAction: "nullify",
},
)
@JoinColumn({ name: "telemetryServiceId" })
public telemetryService?: TelemetryService = undefined;
@JoinColumn({ name: "serviceId" })
public service?: Service = undefined;
@ColumnAccessControl({
create: [],
@ -291,9 +290,8 @@ export default class TelemetryUsageBilling extends BaseModel {
@TableColumn({
type: TableColumnType.ObjectID,
required: true,
title: "Telemetry Service ID",
description:
"ID of your Telemetry Service resource where this object belongs",
title: "Service ID",
description: "ID of your Service resource where this object belongs",
example: "d4e5f6a7-b8c9-0123-def1-234567890123",
})
@Column({
@ -301,7 +299,7 @@ export default class TelemetryUsageBilling extends BaseModel {
nullable: false,
transformer: ObjectID.getDatabaseTransformer(),
})
public telemetryServiceId?: ObjectID = undefined;
public serviceId?: ObjectID = undefined;
@ColumnAccessControl({
create: [],

View file

@ -1,7 +1,6 @@
import AIAgentService from "../Services/AIAgentService";
import LlmProviderService from "../Services/LlmProviderService";
import TelemetryExceptionService from "../Services/TelemetryExceptionService";
import ServiceTelemetryServiceService from "../Services/ServiceTelemetryServiceService";
import ServiceCodeRepositoryService from "../Services/ServiceCodeRepositoryService";
import CodeRepositoryService from "../Services/CodeRepositoryService";
import AIAgentTaskPullRequestService from "../Services/AIAgentTaskPullRequestService";
@ -16,7 +15,6 @@ import Response from "../Utils/Response";
import AIAgent from "../../Models/DatabaseModels/AIAgent";
import LlmProvider from "../../Models/DatabaseModels/LlmProvider";
import TelemetryException from "../../Models/DatabaseModels/TelemetryException";
import ServiceTelemetryService from "../../Models/DatabaseModels/ServiceTelemetryService";
import ServiceCodeRepository from "../../Models/DatabaseModels/ServiceCodeRepository";
import CodeRepository from "../../Models/DatabaseModels/CodeRepository";
import AIAgentTaskPullRequest from "../../Models/DatabaseModels/AIAgentTaskPullRequest";
@ -164,7 +162,7 @@ export default class AIAgentDataAPI {
data["exceptionId"] as string,
);
// Get exception with telemetry service
// Get exception with service
const exception: TelemetryException | null =
await TelemetryExceptionService.findOneById({
id: exceptionId,
@ -174,8 +172,8 @@ export default class AIAgentDataAPI {
stackTrace: true,
exceptionType: true,
fingerprint: true,
telemetryServiceId: true,
telemetryService: {
serviceId: true,
service: {
_id: true,
name: true,
description: true,
@ -206,11 +204,11 @@ export default class AIAgentDataAPI {
exceptionType: exception.exceptionType,
fingerprint: exception.fingerprint,
},
telemetryService: exception.telemetryServiceId
service: exception.serviceId
? {
id: exception.telemetryServiceId.toString(),
name: exception.telemetryService?.name,
description: exception.telemetryService?.description,
id: exception.serviceId.toString(),
name: exception.service?.name,
description: exception.service?.description,
}
: null,
});
@ -220,7 +218,7 @@ export default class AIAgentDataAPI {
},
);
// Get code repositories linked to a telemetry service via Service
// Get code repositories linked to a service
this.router.post(
"/ai-agent-data/get-code-repositories",
async (
@ -242,54 +240,22 @@ export default class AIAgentDataAPI {
);
}
// Get telemetry service ID
if (!data["telemetryServiceId"]) {
// Get service ID (supports both serviceId and legacy telemetryServiceId)
const serviceIdParam: string | undefined =
(data["serviceId"] as string) ||
(data["telemetryServiceId"] as string);
if (!serviceIdParam) {
return Response.sendErrorResponse(
req,
res,
new BadDataException("telemetryServiceId is required"),
new BadDataException("serviceId is required"),
);
}
const telemetryServiceId: ObjectID = new ObjectID(
data["telemetryServiceId"] as string,
);
const serviceId: ObjectID = new ObjectID(serviceIdParam);
// Step 1: Find Services linked to this TelemetryService
const serviceTelemetryServices: Array<ServiceTelemetryService> =
await ServiceTelemetryServiceService.findBy({
query: {
telemetryServiceId: telemetryServiceId,
},
select: {
serviceId: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
if (serviceTelemetryServices.length === 0) {
logger.debug(
`No services found for telemetry service ${telemetryServiceId.toString()}`,
);
return Response.sendJsonObjectResponse(req, res, {
repositories: [],
});
}
// Extract service IDs
const serviceIds: Array<ObjectID> = serviceTelemetryServices
.filter((s: ServiceTelemetryService) => {
return s.serviceId;
})
.map((s: ServiceTelemetryService) => {
return s.serviceId as ObjectID;
});
// Step 2: Find CodeRepositories linked to these Services
// Find CodeRepositories linked to this Service
const repositories: Array<{
id: string;
name: string;
@ -301,70 +267,67 @@ export default class AIAgentDataAPI {
gitHubAppInstallationId: string | null;
}> = [];
for (const serviceId of serviceIds) {
const serviceCodeRepositories: Array<ServiceCodeRepository> =
await ServiceCodeRepositoryService.findBy({
query: {
serviceId: serviceId,
const serviceCodeRepositories: Array<ServiceCodeRepository> =
await ServiceCodeRepositoryService.findBy({
query: {
serviceId: serviceId,
},
select: {
codeRepositoryId: true,
servicePathInRepository: true,
codeRepository: {
_id: true,
name: true,
repositoryHostedAt: true,
organizationName: true,
repositoryName: true,
mainBranchName: true,
gitHubAppInstallationId: true,
},
select: {
codeRepositoryId: true,
servicePathInRepository: true,
codeRepository: {
_id: true,
name: true,
repositoryHostedAt: true,
organizationName: true,
repositoryName: true,
mainBranchName: true,
gitHubAppInstallationId: true,
},
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
for (const scr of serviceCodeRepositories) {
if (scr.codeRepository) {
// Check if we already have this repository
const existingRepo: boolean = repositories.some(
(r: {
id: string;
name: string;
repositoryHostedAt: string;
organizationName: string;
repositoryName: string;
mainBranchName: string;
servicePathInRepository: string | null;
gitHubAppInstallationId: string | null;
}) => {
return r.id === scr.codeRepository?._id?.toString();
},
);
if (!existingRepo) {
repositories.push({
id: scr.codeRepository._id?.toString() || "",
name: scr.codeRepository.name || "",
repositoryHostedAt:
scr.codeRepository.repositoryHostedAt || "",
organizationName: scr.codeRepository.organizationName || "",
repositoryName: scr.codeRepository.repositoryName || "",
mainBranchName: scr.codeRepository.mainBranchName || "main",
servicePathInRepository:
scr.servicePathInRepository || null,
gitHubAppInstallationId:
scr.codeRepository.gitHubAppInstallationId || null,
});
}
for (const scr of serviceCodeRepositories) {
if (scr.codeRepository) {
// Check if we already have this repository
const existingRepo: boolean = repositories.some(
(r: {
id: string;
name: string;
repositoryHostedAt: string;
organizationName: string;
repositoryName: string;
mainBranchName: string;
servicePathInRepository: string | null;
gitHubAppInstallationId: string | null;
}) => {
return r.id === scr.codeRepository?._id?.toString();
},
);
if (!existingRepo) {
repositories.push({
id: scr.codeRepository._id?.toString() || "",
name: scr.codeRepository.name || "",
repositoryHostedAt:
scr.codeRepository.repositoryHostedAt || "",
organizationName: scr.codeRepository.organizationName || "",
repositoryName: scr.codeRepository.repositoryName || "",
mainBranchName: scr.codeRepository.mainBranchName || "main",
servicePathInRepository: scr.servicePathInRepository || null,
gitHubAppInstallationId:
scr.codeRepository.gitHubAppInstallationId || null,
});
}
}
}
logger.debug(
`Found ${repositories.length} code repositories for telemetry service ${telemetryServiceId.toString()}`,
`Found ${repositories.length} code repositories for service ${serviceId.toString()}`,
);
return Response.sendJsonObjectResponse(req, res, {

View file

@ -91,7 +91,6 @@ import ServiceOwnerTeamService from "./ServiceOwnerTeamService";
import ServiceOwnerUserService from "./ServiceOwnerUserService";
import ServiceService from "./ServiceService";
import ServiceMonitorService from "./ServiceMonitorService";
import ServiceTelemetryServiceService from "./ServiceTelemetryServiceService";
import ServiceCodeRepositoryService from "./ServiceCodeRepositoryService";
import ShortLinkService from "./ShortLinkService";
// SMS Log Service
@ -123,7 +122,6 @@ import TeamPermissionService from "./TeamPermissionService";
import TeamComplianceSettingService from "./TeamComplianceSettingService";
// Team
import TeamService from "./TeamService";
import TelemetryServiceService from "./TelemetryServiceService";
import UsageBillingService from "./TelemetryUsageBillingService";
import UserCallService from "./UserCallService";
import UserEmailService from "./UserEmailService";
@ -315,8 +313,6 @@ const services: Array<BaseService> = [
MonitorGroupOwnerUserService,
MonitorGroupOwnerTeamService,
TelemetryServiceService,
// On Call Duty Policy Schedule
OnCallDutyPolicyScheduleService,
OnCallDutyPolicyScheduleLayerUserService,
@ -331,7 +327,6 @@ const services: Array<BaseService> = [
ServiceOwnerUserService,
ServiceDependencyService,
ServiceMonitorService,
ServiceTelemetryServiceService,
ServiceCodeRepositoryService,
TelemetryExceptionService,

View file

@ -4,8 +4,8 @@ import ObjectID from "../../Types/ObjectID";
import Metric, {
AggregationTemporality,
} from "../../Models/AnalyticsModels/Metric";
import TelemetryService from "../../Models/DatabaseModels/TelemetryService";
import TelemetryServiceService from "../../Server/Services/TelemetryServiceService";
import Service from "../../Models/DatabaseModels/Service";
import ServiceService from "../../Server/Services/ServiceService";
import { DEFAULT_RETENTION_IN_DAYS } from "../../Models/DatabaseModels/TelemetryUsageBilling";
import TelemetryUtil from "../../Server/Utils/Telemetry/Telemetry";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
@ -30,37 +30,35 @@ export default class OTelIngestService {
serviceId: ObjectID;
dataRententionInDays: number;
}> {
const service: TelemetryService | null =
await TelemetryServiceService.findOneBy({
query: {
projectId: data.projectId,
name: data.serviceName,
},
select: {
_id: true,
retainTelemetryDataForDays: true,
},
props: {
isRoot: true,
},
});
const service: Service | null = await ServiceService.findOneBy({
query: {
projectId: data.projectId,
name: data.serviceName,
},
select: {
_id: true,
retainTelemetryDataForDays: true,
},
props: {
isRoot: true,
},
});
if (!service) {
// create service
const newService: TelemetryService = new TelemetryService();
const newService: Service = new Service();
newService.projectId = data.projectId;
newService.name = data.serviceName;
newService.description = data.serviceName;
newService.retainTelemetryDataForDays = DEFAULT_RETENTION_IN_DAYS;
const createdService: TelemetryService =
await TelemetryServiceService.create({
data: newService,
props: {
isRoot: true,
},
});
const createdService: Service = await ServiceService.create({
data: newService,
props: {
isRoot: true,
},
});
return {
serviceId: createdService.id!,

View file

@ -3,6 +3,8 @@ import { OnCreate } from "../Types/Database/Hooks";
import DatabaseService from "./DatabaseService";
import ArrayUtil from "../../Utils/Array";
import { BrightColors } from "../../Types/BrandColors";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import Model from "../../Models/DatabaseModels/Service";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
@ -23,6 +25,27 @@ export class Service extends DatabaseService<Model> {
createBy: createBy,
};
}
@CaptureSpan()
public async getTelemetryDataRetentionInDays(
serviceId: ObjectID,
): Promise<number> {
const service: Model | null = await this.findOneById({
id: serviceId,
select: {
retainTelemetryDataForDays: true,
},
props: {
isRoot: true,
},
});
if (!service) {
throw new BadDataException("Service not found");
}
return service.retainTelemetryDataForDays || 15; // default is 15 days.
}
}
export default new Service();

View file

@ -1,59 +0,0 @@
import BadDataException from "../../Types/Exception/BadDataException";
import CreateBy from "../Types/Database/CreateBy";
import { OnCreate } from "../Types/Database/Hooks";
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/ServiceTelemetryService";
import ObjectID from "../../Types/ObjectID";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
@CaptureSpan()
protected override async onBeforeCreate(
createBy: CreateBy<Model>,
): Promise<OnCreate<Model>> {
// select a random color.
if (!createBy.data.serviceId && !createBy.data.service) {
throw new BadDataException("service is required");
}
if (!createBy.data.telemetryService && !createBy.data.telemetryServiceId) {
throw new BadDataException("telemetryService is required");
}
// serviceId and dependencyServiceId should not be the same
const serviceId: string | ObjectID | undefined =
createBy.data.serviceId || createBy.data.service?._id;
const telemetryServiceId: string | ObjectID | undefined =
createBy.data.telemetryServiceId || createBy.data.telemetryService?._id;
// check if this telemetryService is already added to the service for this service.
const existingtelemetryService: Model | null = await this.findOneBy({
query: {
serviceId: serviceId as ObjectID,
telemetryServiceId: telemetryServiceId as ObjectID,
},
props: {
isRoot: true,
},
});
if (existingtelemetryService) {
throw new BadDataException(
"Telemetry Service already exists for this service",
);
}
return {
carryForward: null,
createBy: createBy,
};
}
}
export default new Service();

View file

@ -1,53 +0,0 @@
import CreateBy from "../Types/Database/CreateBy";
import { OnCreate } from "../Types/Database/Hooks";
import DatabaseService from "./DatabaseService";
import ArrayUtil from "../../Utils/Array";
import { BrightColors } from "../../Types/BrandColors";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import Model from "../../Models/DatabaseModels/TelemetryService";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
export class Service extends DatabaseService<Model> {
public constructor() {
super(Model);
}
@CaptureSpan()
protected override async onBeforeCreate(
createBy: CreateBy<Model>,
): Promise<OnCreate<Model>> {
createBy.data.telemetryServiceToken = ObjectID.generate();
// select a random color.
createBy.data.serviceColor = ArrayUtil.selectItemByRandom(BrightColors);
return {
carryForward: null,
createBy: createBy,
};
}
@CaptureSpan()
public async getTelemetryDataRetentionInDays(
telemetryServiceId: ObjectID,
): Promise<number> {
const project: Model | null = await this.findOneById({
id: telemetryServiceId,
select: {
retainTelemetryDataForDays: true,
},
props: {
isRoot: true,
},
});
if (!project) {
throw new BadDataException("Project not found");
}
return project.retainTelemetryDataForDays || 15; // default is 15 days.
}
}
export default new Service();

View file

@ -11,7 +11,7 @@ import ObjectID from "../../Types/ObjectID";
import Model, {
DEFAULT_RETENTION_IN_DAYS,
} from "../../Models/DatabaseModels/TelemetryUsageBilling";
import TelemetryServiceService from "./TelemetryServiceService";
import ServiceService from "./ServiceService";
import SpanService from "./SpanService";
import LogService from "./LogService";
import MetricService from "./MetricService";
@ -20,7 +20,7 @@ import AnalyticsQueryHelper from "../Types/AnalyticsDatabase/QueryHelper";
import DiskSize from "../../Types/DiskSize";
import logger from "../Utils/Logger";
import PositiveNumber from "../../Types/PositiveNumber";
import TelemetryServiceModel from "../../Models/DatabaseModels/TelemetryService";
import ServiceModel from "../../Models/DatabaseModels/Service";
import {
AverageSpanRowSizeInBytes,
AverageLogRowSizeInBytes,
@ -97,8 +97,8 @@ export class Service extends DatabaseService<Model> {
const startOfDay: Date = OneUptimeDate.getStartOfDay(usageDate);
const endOfDay: Date = OneUptimeDate.getEndOfDay(usageDate);
const telemetryServices: Array<TelemetryServiceModel> =
await TelemetryServiceService.findBy({
const services: Array<ServiceModel> =
await ServiceService.findBy({
query: {
projectId: data.projectId,
},
@ -113,12 +113,12 @@ export class Service extends DatabaseService<Model> {
},
});
if (!telemetryServices || telemetryServices.length === 0) {
if (!services || services.length === 0) {
return;
}
for (const telemetryService of telemetryServices) {
if (!telemetryService?.id) {
for (const service of services) {
if (!service?.id) {
continue;
}
@ -126,7 +126,7 @@ export class Service extends DatabaseService<Model> {
query: {
projectId: data.projectId,
productType: data.productType,
telemetryServiceId: telemetryService.id,
serviceId: service.id,
day: usageDayString,
},
select: {
@ -148,7 +148,7 @@ export class Service extends DatabaseService<Model> {
const spanCount: PositiveNumber = await SpanService.countBy({
query: {
projectId: data.projectId,
serviceId: telemetryService.id,
serviceId: service.id,
startTime: AnalyticsQueryHelper.inBetween(startOfDay, endOfDay),
},
skip: 0,
@ -162,7 +162,7 @@ export class Service extends DatabaseService<Model> {
await ExceptionInstanceService.countBy({
query: {
projectId: data.projectId,
serviceId: telemetryService.id,
serviceId: service.id,
time: AnalyticsQueryHelper.inBetween(startOfDay, endOfDay),
},
skip: 0,
@ -186,7 +186,7 @@ export class Service extends DatabaseService<Model> {
const count: PositiveNumber = await LogService.countBy({
query: {
projectId: data.projectId,
serviceId: telemetryService.id,
serviceId: service.id,
time: AnalyticsQueryHelper.inBetween(startOfDay, endOfDay),
},
skip: 0,
@ -207,7 +207,7 @@ export class Service extends DatabaseService<Model> {
const count: PositiveNumber = await MetricService.countBy({
query: {
projectId: data.projectId,
serviceId: telemetryService.id,
serviceId: service.id,
time: AnalyticsQueryHelper.inBetween(startOfDay, endOfDay),
},
skip: 0,
@ -227,7 +227,7 @@ export class Service extends DatabaseService<Model> {
}
} catch (error) {
logger.error(
`Failed to compute telemetry usage for service ${telemetryService.id?.toString()}:`,
`Failed to compute telemetry usage for service ${service.id?.toString()}:`,
);
logger.error(error as Error);
continue;
@ -244,13 +244,13 @@ export class Service extends DatabaseService<Model> {
}
const dataRetentionInDays: number =
telemetryService.retainTelemetryDataForDays ||
service.retainTelemetryDataForDays ||
DEFAULT_RETENTION_IN_DAYS;
await this.updateUsageBilling({
projectId: data.projectId,
productType: data.productType,
telemetryServiceId: telemetryService.id,
serviceId: service.id,
dataIngestedInGB: estimatedGigabytes,
retentionInDays: dataRetentionInDays,
usageDate: usageDate,
@ -262,7 +262,7 @@ export class Service extends DatabaseService<Model> {
public async updateUsageBilling(data: {
projectId: ObjectID;
productType: ProductType;
telemetryServiceId: ObjectID;
serviceId: ObjectID;
dataIngestedInGB: number;
retentionInDays: number;
usageDate?: Date;
@ -298,7 +298,7 @@ export class Service extends DatabaseService<Model> {
query: {
projectId: data.projectId,
productType: data.productType,
telemetryServiceId: data.telemetryServiceId,
serviceId: data.serviceId,
isReportedToBillingProvider: false,
day: usageDayString,
},
@ -347,7 +347,7 @@ export class Service extends DatabaseService<Model> {
usageBilling.projectId = data.projectId;
usageBilling.productType = data.productType;
usageBilling.dataIngestedInGB = new Decimal(data.dataIngestedInGB);
usageBilling.telemetryServiceId = data.telemetryServiceId;
usageBilling.serviceId = data.serviceId;
usageBilling.retainTelemetryDataForDays = data.retentionInDays;
usageBilling.isReportedToBillingProvider = false;
usageBilling.createdAt = usageDate;

View file

@ -3,7 +3,7 @@ import ObjectID from "../../../Types/ObjectID";
import CaptureSpan from "./CaptureSpan";
import MetricType from "../../../Models/DatabaseModels/MetricType";
import MetricTypeService from "../../Services/MetricTypeService";
import TelemetryService from "../../../Models/DatabaseModels/TelemetryService";
import Service from "../../../Models/DatabaseModels/Service";
import Dictionary from "../../../Types/Dictionary";
export type AttributeType = string | number | boolean | null;
@ -22,7 +22,7 @@ export default class TelemetryUtil {
name: metricName,
},
select: {
telemetryServices: true,
services: true,
name: true,
description: true,
unit: true,
@ -35,19 +35,19 @@ export default class TelemetryUtil {
const metricTypeInMap: MetricType =
data.metricNameServiceNameMap[metricName]!;
// check if telemetry services are same as the ones in the map
const telemetryServicesInMap: Array<ObjectID> =
metricTypeInMap?.telemetryServices?.map((service: TelemetryService) => {
// check if services are same as the ones in the map
const servicesInMap: Array<ObjectID> =
metricTypeInMap?.services?.map((service: Service) => {
return service.id!;
}) || [];
if (metricType) {
if (!metricType.telemetryServices) {
metricType.telemetryServices = [];
if (!metricType.services) {
metricType.services = [];
}
const telemetryServiceIds: Array<ObjectID> =
metricType.telemetryServices!.map((service: TelemetryService) => {
const serviceIds: Array<ObjectID> =
metricType.services!.map((service: Service) => {
return service.id!;
});
@ -65,19 +65,19 @@ export default class TelemetryUtil {
metricType.unit = metricTypeInMap.unit || "";
}
// check if telemetry services are same
// check if services are same
for (const telemetryServiceId of telemetryServicesInMap) {
for (const serviceId of servicesInMap) {
if (
telemetryServiceIds.filter((serviceId: ObjectID) => {
return serviceId.toString() === telemetryServiceId.toString();
serviceIds.filter((existingServiceId: ObjectID) => {
return existingServiceId.toString() === serviceId.toString();
}).length === 0
) {
isSame = false;
// add the service id to the list
const telemetryService: TelemetryService = new TelemetryService();
telemetryService.id = telemetryServiceId;
metricType.telemetryServices!.push(telemetryService);
const service: Service = new Service();
service.id = serviceId;
metricType.services!.push(service);
}
}
@ -88,7 +88,7 @@ export default class TelemetryUtil {
await MetricTypeService.updateOneById({
id: metricType.id!,
data: {
telemetryServices: metricType.telemetryServices || [],
services: metricType.services || [],
description: metricTypeInMap.description || "",
unit: metricTypeInMap.unit || "",
},
@ -104,12 +104,12 @@ export default class TelemetryUtil {
metricType.description = metricTypeInMap.description || "";
metricType.unit = metricTypeInMap.unit || "";
metricType.projectId = data.projectId;
metricType.telemetryServices = [];
metricType.services = [];
for (const telemetryServiceId of telemetryServicesInMap) {
const telemetryService: TelemetryService = new TelemetryService();
telemetryService.id = telemetryServiceId;
metricType.telemetryServices!.push(telemetryService);
for (const serviceId of servicesInMap) {
const service: Service = new Service();
service.id = serviceId;
metricType.services!.push(service);
}
// save metric type

View file

@ -19,7 +19,7 @@ import API from "../../Utils/API/API";
import { APP_API_URL } from "../../Config";
import PageLoader from "../Loader/PageLoader";
import ErrorMessage from "../ErrorMessage/ErrorMessage";
import TelemetryService from "../../../Models/DatabaseModels/TelemetryService";
import Service from "../../../Models/DatabaseModels/Service";
import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
import ListResult from "../../../Types/BaseDatabase/ListResult";
@ -99,7 +99,7 @@ const LogsViewer: FunctionComponent<ComponentProps> = (
const [isPageLoading, setIsPageLoading] = useState<boolean>(true);
const [pageError, setPageError] = useState<string>("");
const [serviceMap, setServiceMap] = useState<Dictionary<TelemetryService>>(
const [serviceMap, setServiceMap] = useState<Dictionary<Service>>(
{},
);
@ -237,15 +237,15 @@ const LogsViewer: FunctionComponent<ComponentProps> = (
}
}, [displayedLogs, selectedLogId]);
const loadTelemetryServices: PromiseVoidFunction =
const loadServices: PromiseVoidFunction =
useCallback(async (): Promise<void> => {
try {
setIsPageLoading(true);
setPageError("");
const telemetryServices: ListResult<TelemetryService> =
const telemetryServices: ListResult<Service> =
await ModelAPI.getList({
modelType: TelemetryService,
modelType: Service,
query: {},
select: {
name: true,
@ -257,9 +257,9 @@ const LogsViewer: FunctionComponent<ComponentProps> = (
name: SortOrder.Ascending,
},
});
const services: Dictionary<TelemetryService> = {};
const services: Dictionary<Service> = {};
telemetryServices.data.forEach((service: TelemetryService) => {
telemetryServices.data.forEach((service: Service) => {
if (!service.id) {
return;
}
@ -315,8 +315,8 @@ const LogsViewer: FunctionComponent<ComponentProps> = (
}, []);
useEffect(() => {
void loadTelemetryServices();
}, [loadTelemetryServices]);
void loadServices();
}, [loadServices]);
const resetPage: () => void = (): void => {
if (props.onPageChange) {

View file

@ -1,6 +1,6 @@
import React, { FunctionComponent, ReactElement, useMemo } from "react";
import Log from "../../../../Models/AnalyticsModels/Log";
import TelemetryService from "../../../../Models/DatabaseModels/TelemetryService";
import Service from "../../../../Models/DatabaseModels/Service";
import Dictionary from "../../../../Types/Dictionary";
import Route from "../../../../Types/API/Route";
import URL from "../../../../Types/API/URL";
@ -14,7 +14,7 @@ import SeverityBadge from "./SeverityBadge";
export interface LogDetailsPanelProps {
log: Log;
serviceMap: Dictionary<TelemetryService>;
serviceMap: Dictionary<Service>;
onClose?: () => void;
getTraceRoute?:
| ((traceId: string, log: Log) => Route | URL | undefined)
@ -69,7 +69,7 @@ const LogDetailsPanel: FunctionComponent<LogDetailsPanelProps> = (
): ReactElement => {
const variant: "floating" | "embedded" = props.variant || "floating";
const serviceId: string = props.log.serviceId?.toString() || "";
const service: TelemetryService | undefined = props.serviceMap[serviceId];
const service: Service | undefined = props.serviceMap[serviceId];
const serviceName: string = service?.name || serviceId || "Unknown service";
const serviceColor: string =
(service?.serviceColor && service?.serviceColor.toString()) || "#64748b";

View file

@ -1,6 +1,6 @@
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import Log from "../../../../Models/AnalyticsModels/Log";
import TelemetryService from "../../../../Models/DatabaseModels/TelemetryService";
import Service from "../../../../Models/DatabaseModels/Service";
import Dictionary from "../../../../Types/Dictionary";
import OneUptimeDate from "../../../../Types/Date";
import CopyTextButton from "../../CopyTextButton/CopyTextButton";
@ -13,7 +13,7 @@ import IconProp from "../../../../Types/Icon/IconProp";
export interface LogsTableProps {
logs: Array<Log>;
serviceMap: Dictionary<TelemetryService>;
serviceMap: Dictionary<Service>;
isLoading: boolean;
emptyMessage?: string | undefined;
onRowClick: (log: Log, rowId: string) => void;
@ -151,7 +151,7 @@ const LogsTable: FunctionComponent<LogsTableProps> = (
{props.logs.map((log: Log, index: number) => {
const rowId: string = resolveLogIdentifier(log, index);
const serviceId: string = log.serviceId?.toString() || "";
const service: TelemetryService | undefined =
const service: Service | undefined =
props.serviceMap[serviceId];
const serviceName: string =
service?.name || serviceId || "Unknown";

View file

@ -1,11 +1,11 @@
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import { JSONObject } from "Common/Types/JSON";
import Card from "Common/UI/Components/Card/Card";
import Detail from "Common/UI/Components/Detail/Detail";
import Field from "Common/UI/Components/Detail/Field";
import FieldType from "Common/UI/Components/Types/FieldType";
import React, { FunctionComponent, ReactElement } from "react";
import TelemetryServiceElement from "../TelemetryService/TelemetryServiceElement";
import ServiceElement from "../Service/ServiceElement";
export interface ComponentProps {
exceptionType?: string | undefined;
@ -16,7 +16,7 @@ export interface ComponentProps {
lastSeenAt?: Date | undefined;
occuranceCount?: number | undefined;
attributes?: JSONObject | undefined;
telemetryService?: TelemetryService | undefined;
telemetryService?: Service | undefined;
}
const ExceptionDetail: FunctionComponent<ComponentProps> = (
@ -104,7 +104,7 @@ const ExceptionDetail: FunctionComponent<ComponentProps> = (
fieldType: FieldType.Element,
getElement: () => {
return (
<TelemetryServiceElement telemetryService={props.telemetryService!} />
<ServiceElement telemetryService={props.telemetryService!} />
);
},
});

View file

@ -25,7 +25,7 @@ import OneUptimeDate from "Common/Types/Date";
import UserUtil from "Common/UI/Utils/User";
export interface ComponentProps {
telemetryServiceId?: ObjectID | undefined;
serviceId?: ObjectID | undefined;
query: Query<TelemetryException>;
title: string;
description: string;
@ -59,8 +59,8 @@ const TelemetryExceptionTable: FunctionComponent<ComponentProps> = (
}}
query={{
projectId: ProjectUtil.getCurrentProjectId()!,
telemetryServiceId: props.telemetryServiceId
? props.telemetryServiceId
serviceId: props.serviceId
? props.serviceId
: undefined,
...props.query,
}}
@ -430,7 +430,7 @@ const TelemetryExceptionTable: FunctionComponent<ComponentProps> = (
},
{
field: {
telemetryService: {
service: {
name: true,
serviceColor: true,
},
@ -438,14 +438,14 @@ const TelemetryExceptionTable: FunctionComponent<ComponentProps> = (
title: "Service",
type: FieldType.Entity,
getElement: (exception: TelemetryException) => {
if (!exception.telemetryService) {
if (!exception.service) {
// this should never happen.
return <div>Unknown</div>;
}
return (
<TelemetryServiceElement
telemetryService={exception.telemetryService!}
telemetryService={exception.service!}
/>
);
},

View file

@ -1,7 +1,7 @@
import MonitorStepExceptionMonitor, {
MonitorStepExceptionMonitorUtil,
} from "Common/Types/Monitor/MonitorStepExceptionMonitor";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, {
FunctionComponent,
ReactElement,
@ -25,7 +25,7 @@ export interface ComponentProps {
onMonitorStepExceptionMonitorChanged: (
monitorStepExceptionMonitor: MonitorStepExceptionMonitor,
) => void;
telemetryServices: Array<TelemetryService>;
telemetryServices: Array<Service>;
}
type ExceptionMonitorFormValues = {
@ -217,7 +217,7 @@ const ExceptionMonitorStepForm: FunctionComponent<ComponentProps> = (
},
fieldType: FormFieldSchemaType.MultiSelectDropdown,
dropdownOptions: props.telemetryServices.map(
(service: TelemetryService): { label: string; value: string } => {
(service: Service): { label: string; value: string } => {
return {
label: service.name || "Untitled Service",
value: service.id?.toString() || "",

View file

@ -1,5 +1,5 @@
import MonitorStepLogMonitor from "Common/Types/Monitor/MonitorStepLogMonitor";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { FunctionComponent, ReactElement } from "react";
import BasicForm from "Common/UI/Components/Forms/BasicForm";
import LogSeverity from "Common/Types/Log/LogSeverity";
@ -16,7 +16,7 @@ export interface ComponentProps {
monitorStepLogMonitor: MonitorStepLogMonitor,
) => void;
attributeKeys: Array<string>;
telemetryServices: Array<TelemetryService>;
telemetryServices: Array<Service>;
}
const LogMonitorStepForm: FunctionComponent<ComponentProps> = (
@ -137,7 +137,7 @@ const LogMonitorStepForm: FunctionComponent<ComponentProps> = (
},
fieldType: FormFieldSchemaType.MultiSelectDropdown,
dropdownOptions: props.telemetryServices.map(
(telemetryService: TelemetryService) => {
(telemetryService: Service) => {
return {
label: telemetryService.name!,
value: telemetryService.id?.toString() || "",

View file

@ -43,7 +43,7 @@ import React, {
} from "react";
import LogMonitorStepForm from "./LogMonitor/LogMonitorStepFrom";
import TraceMonitorStepForm from "./TraceMonitor/TraceMonitorStepForm";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import ModelAPI, { ListResult } from "Common/UI/Utils/ModelAPI/ModelAPI";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import SortOrder from "Common/Types/BaseDatabase/SortOrder";
@ -100,8 +100,8 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
setShowSyntheticMonitorAdvancedOptions,
] = useState<boolean>(false);
const [telemetryServices, setTelemetryServices] = useState<
Array<TelemetryService>
const [telemetryServices, setServices] = useState<
Array<Service>
>([]);
const [attributeKeys, setAttributeKeys] = useState<Array<string>>([]);
const [error, setError] = useState<string>("");
@ -151,11 +151,11 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
}
};
const fetchTelemetryServices: PromiseVoidFunction =
const fetchServices: PromiseVoidFunction =
async (): Promise<void> => {
const telemetryServicesResult: ListResult<TelemetryService> =
await ModelAPI.getList<TelemetryService>({
modelType: TelemetryService,
const telemetryServicesResult: ListResult<Service> =
await ModelAPI.getList<Service>({
modelType: Service,
query: {
projectId: ProjectUtil.getCurrentProjectId()!,
},
@ -174,15 +174,15 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
throw telemetryServicesResult;
}
setTelemetryServices(telemetryServicesResult.data);
setServices(telemetryServicesResult.data);
};
const fetchTelemetryServicesAndAttributes: PromiseVoidFunction =
const fetchServicesAndAttributes: PromiseVoidFunction =
async (): Promise<void> => {
setIsLoading(true);
setError("");
try {
await fetchTelemetryServices();
await fetchServices();
if (props.monitorType === MonitorType.Logs) {
await fetchLogAttributes();
@ -201,7 +201,7 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
};
useEffect(() => {
fetchTelemetryServicesAndAttributes().catch((err: Error) => {
fetchServicesAndAttributes().catch((err: Error) => {
setError(API.getFriendlyErrorMessage(err as Error));
});
}, [props.monitorType]);

View file

@ -1,7 +1,7 @@
import MonitorStepTraceMonitor, {
MonitorStepTraceMonitorUtil,
} from "Common/Types/Monitor/MonitorStepTraceMonitor";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { FunctionComponent, ReactElement } from "react";
import BasicForm from "Common/UI/Components/Forms/BasicForm";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
@ -17,7 +17,7 @@ export interface ComponentProps {
monitorStepTraceMonitor: MonitorStepTraceMonitor,
) => void;
attributeKeys: Array<string>;
telemetryServices: Array<TelemetryService>;
telemetryServices: Array<Service>;
}
const TraceMonitorStepForm: FunctionComponent<ComponentProps> = (
@ -136,7 +136,7 @@ const TraceMonitorStepForm: FunctionComponent<ComponentProps> = (
},
fieldType: FormFieldSchemaType.MultiSelectDropdown,
dropdownOptions: props.telemetryServices.map(
(telemetryService: TelemetryService) => {
(telemetryService: Service) => {
return {
label: telemetryService.name!,
value: telemetryService.id?.toString() || "",

View file

@ -23,7 +23,7 @@ import Route from "Common/Types/API/Route";
export interface ComponentProps {
id: string;
telemetryServiceIds?: Array<ObjectID> | undefined;
serviceIds?: Array<ObjectID> | undefined;
enableRealtime?: boolean;
traceIds?: Array<string> | undefined;
spanIds?: Array<string> | undefined;
@ -41,8 +41,8 @@ const DashboardLogsViewer: FunctionComponent<ComponentProps> = (
const refreshQuery: RefreshQueryFunction = (): Query<Log> => {
const query: Query<Log> = {};
if (props.telemetryServiceIds && props.telemetryServiceIds.length > 0) {
query.serviceId = new Includes(props.telemetryServiceIds);
if (props.serviceIds && props.serviceIds.length > 0) {
query.serviceId = new Includes(props.serviceIds);
}
if (props.traceIds && props.traceIds.length > 0) {
@ -87,7 +87,7 @@ const DashboardLogsViewer: FunctionComponent<ComponentProps> = (
setFilterOptions(refreshQuery());
setPage(1);
}, [
props.telemetryServiceIds,
props.serviceIds,
props.traceIds,
props.spanIds,
props.logQuery,

View file

@ -2,7 +2,7 @@ import ProjectUtil from "Common/UI/Utils/Project";
import SortOrder from "Common/Types/BaseDatabase/SortOrder";
import ObjectID from "Common/Types/ObjectID";
import FieldType from "Common/UI/Components/Types/FieldType";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import Navigation from "Common/UI/Utils/Navigation";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import PageMap from "../../Utils/PageMap";
@ -12,18 +12,18 @@ import React, { Fragment, FunctionComponent, ReactElement } from "react";
import ModelTable from "Common/UI/Components/ModelTable/ModelTable";
import MetricType from "Common/Models/DatabaseModels/MetricType";
import Includes from "Common/Types/BaseDatabase/Includes";
import TelemetryServicesElement from "../TelemetryService/TelemetryServiceElements";
import ServicesElement from "../Service/ServiceElements";
import MetricsAggregationType from "Common/Types/Metrics/MetricsAggregationType";
export interface ComponentProps {
telemetryServiceIds?: Array<ObjectID> | undefined;
serviceIds?: Array<ObjectID> | undefined;
}
const MetricsTable: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const telemetryServiceFilterIds: Array<ObjectID> =
props.telemetryServiceIds || [];
const serviceFilterIds: Array<ObjectID> =
props.serviceIds || [];
return (
<Fragment>
@ -59,19 +59,19 @@ const MetricsTable: FunctionComponent<ComponentProps> = (
const metricAttributes: Record<string, string> = {};
if (telemetryServiceFilterIds.length === 1) {
const telemetryServiceId: ObjectID | undefined =
telemetryServiceFilterIds[0];
if (serviceFilterIds.length === 1) {
const serviceId: ObjectID | undefined =
serviceFilterIds[0];
const serviceIdString: string | undefined =
telemetryServiceId?.toString();
serviceId?.toString();
if (serviceIdString) {
metricAttributes["oneuptime.service.id"] = serviceIdString;
const matchingService: TelemetryService | undefined = (
item.telemetryServices || []
).find((service: TelemetryService) => {
const matchingService: Service | undefined = (
item.services || []
).find((service: Service) => {
return service._id?.toString() === serviceIdString;
});
@ -102,13 +102,13 @@ const MetricsTable: FunctionComponent<ComponentProps> = (
}}
query={{
projectId: ProjectUtil.getCurrentProjectId()!,
telemetryServices:
telemetryServiceFilterIds.length > 0
? new Includes(telemetryServiceFilterIds)
services:
serviceFilterIds.length > 0
? new Includes(serviceFilterIds)
: undefined,
}}
selectMoreFields={{
telemetryServices: {
services: {
_id: true,
name: true,
serviceColor: true,
@ -128,13 +128,13 @@ const MetricsTable: FunctionComponent<ComponentProps> = (
},
{
field: {
telemetryServices: {
services: {
name: true,
},
},
title: "Telemetry Service",
title: "Service",
type: FieldType.EntityArray,
filterEntityType: TelemetryService,
filterEntityType: Service,
filterQuery: {
projectId: ProjectUtil.getCurrentProjectId()!,
},
@ -154,18 +154,18 @@ const MetricsTable: FunctionComponent<ComponentProps> = (
},
{
field: {
telemetryServices: {
services: {
name: true,
_id: true,
serviceColor: true,
},
},
title: "Telemetry Services",
title: "Services",
type: FieldType.Element,
getElement: (item: MetricType): ReactElement => {
return (
<TelemetryServicesElement
telemetryServices={item.telemetryServices || []}
<ServicesElement
telemetryServices={item.services || []}
/>
);
},

View file

@ -19,7 +19,7 @@ import React, {
} from "react";
import ComponentLoader from "Common/UI/Components/ComponentLoader/ComponentLoader";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import { JSONObject } from "Common/Types/JSON";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import ListResult from "Common/Types/BaseDatabase/ListResult";
@ -30,7 +30,7 @@ import HTTPErrorResponse from "Common/Types/API/HTTPErrorResponse";
import API from "Common/UI/Utils/API/API";
import Includes from "Common/Types/BaseDatabase/Includes";
import OneUptimeDate from "Common/Types/Date";
import TelemetryServicesElement from "../../TelemetryService/TelemetryServiceElements";
import ServicesElement from "../../Service/ServiceElements";
import { SpanStatus } from "Common/Models/AnalyticsModels/Span";
import ObjectID from "Common/Types/ObjectID";
import SpanUtil from "../../../Utils/SpanUtil";
@ -49,7 +49,7 @@ export interface LogMonitorStepView {
body: string | undefined;
severityTexts: Array<string> | undefined;
attributes: JSONObject | undefined;
telemetryServices: Array<TelemetryService> | undefined;
telemetryServices: Array<Service> | undefined;
lastXSecondsOfLogs: number | undefined;
}
@ -57,7 +57,7 @@ export interface TraceMonitorStepView {
spanName: string | undefined;
spanStatuses: Array<SpanStatus> | undefined;
attributes: JSONObject | undefined;
telemetryServices: Array<TelemetryService> | undefined;
telemetryServices: Array<Service> | undefined;
lastXSecondsOfSpans: number | undefined;
}
@ -66,8 +66,8 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
): ReactElement => {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | undefined>(undefined);
const [telemetryServices, setTelemetryServices] = useState<
Array<TelemetryService> | undefined
const [telemetryServices, setServices] = useState<
Array<Service> | undefined
>(undefined);
// this field is used for most monitor types
@ -91,7 +91,7 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
lastXSecondsOfLogs: undefined,
};
const fetchTelemetryServices: PromiseVoidFunction =
const fetchServices: PromiseVoidFunction =
async (): Promise<void> => {
let telemetryServiceIds: Array<ObjectID> = [];
@ -113,9 +113,9 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
props.monitorStep.data?.traceMonitor?.telemetryServiceIds || [];
}
const telemetryServicesResult: ListResult<TelemetryService> =
await ModelAPI.getList<TelemetryService>({
modelType: TelemetryService,
const telemetryServicesResult: ListResult<Service> =
await ModelAPI.getList<Service>({
modelType: Service,
query: {
projectId: ProjectUtil.getCurrentProjectId()!,
_id: new Includes(telemetryServiceIds),
@ -136,7 +136,7 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
throw telemetryServicesResult;
}
setTelemetryServices(telemetryServicesResult.data);
setServices(telemetryServicesResult.data);
};
const loadComponent: PromiseVoidFunction = async (): Promise<void> => {
@ -146,7 +146,7 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
props.monitorType === MonitorType.Logs ||
props.monitorType === MonitorType.Traces
) {
await fetchTelemetryServices();
await fetchServices();
}
} catch (err) {
setError(API.getFriendlyErrorMessage(err as Error));
@ -385,7 +385,7 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
placeholder: "No telemetry services entered",
getElement: (): ReactElement => {
return (
<TelemetryServicesElement telemetryServices={telemetryServices} />
<ServicesElement telemetryServices={telemetryServices} />
);
},
});
@ -484,7 +484,7 @@ const MonitorStepElement: FunctionComponent<ComponentProps> = (
placeholder: "No telemetry services entered",
getElement: (): ReactElement => {
return (
<TelemetryServicesElement telemetryServices={telemetryServices} />
<ServicesElement telemetryServices={telemetryServices} />
);
},
});

View file

@ -1,5 +1,5 @@
import SpanUtil, { DivisibilityFactor } from "../../Utils/SpanUtil";
import TelemetryServiceElement from "../TelemetryService/TelemetryServiceElement";
import ServiceElement from "../Service/ServiceElement";
import SpanStatusElement from "./SpanStatusElement";
import SortOrder from "Common/Types/BaseDatabase/SortOrder";
import CodeType from "Common/Types/Code/CodeType";
@ -29,7 +29,7 @@ import Span, {
SpanEvent,
SpanEventType,
} from "Common/Models/AnalyticsModels/Span";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { FunctionComponent, ReactElement, useEffect } from "react";
import { JSONObject } from "Common/Types/JSON";
import Text from "Common/Types/Text";
@ -43,7 +43,7 @@ export interface ComponentProps {
openTelemetrySpanId: string;
traceStartTimeInUnixNano: number;
onClose: () => void;
telemetryService: TelemetryService;
telemetryService: Service;
divisibilityFactor: DivisibilityFactor;
}
@ -596,7 +596,7 @@ const SpanViewer: FunctionComponent<ComponentProps> = (
fieldType: FieldType.Element,
getElement: () => {
return (
<TelemetryServiceElement
<ServiceElement
telemetryService={telemetryService}
onNavigateComplete={() => {
onClose();

View file

@ -6,11 +6,11 @@ import ObjectID from "Common/Types/ObjectID";
import ColorSquareCube from "Common/UI/Components/ColorSquareCube/ColorSquareCube";
import AppLink from "../AppLink/AppLink";
import { GetReactElementFunction } from "Common/UI/Types/FunctionTypes";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { FunctionComponent, ReactElement } from "react";
export interface ComponentProps {
telemetryService: TelemetryService;
telemetryService: Service;
onNavigateComplete?: (() => void) | undefined;
telemetryServiceNameClassName?: string;
}

View file

@ -1,10 +1,10 @@
import TelemetryServiceElement from "./TelemetryServiceElement";
import TableColumnListComponent from "Common/UI/Components/TableColumnList/TableColumnListComponent";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { FunctionComponent, ReactElement } from "react";
export interface ComponentProps {
telemetryServices: Array<TelemetryService>;
telemetryServices: Array<Service>;
onNavigateComplete?: (() => void) | undefined;
}
@ -15,7 +15,7 @@ const TelemetryServicesElement: FunctionComponent<ComponentProps> = (
<TableColumnListComponent
items={props.telemetryServices}
moreText="more services"
getEachElement={(telemetryService: TelemetryService) => {
getEachElement={(telemetryService: Service) => {
return (
<TelemetryServiceElement
telemetryService={telemetryService}

View file

@ -9,7 +9,7 @@ import Monitor from "Common/Models/DatabaseModels/Monitor";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import ActionButtonSchema from "Common/UI/Components/ActionButton/ActionButtonSchema";
import { CardButtonSchema } from "Common/UI/Components/Card/Card";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
import PageMap from "../../Utils/PageMap";
import TelemetryServiceElement from "./TelemetryServiceElement";
@ -29,8 +29,8 @@ const TelemetryServiceTable: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
return (
<ModelTable<TelemetryService>
modelType={TelemetryService}
<ModelTable<Service>
modelType={Service}
id="services-table"
isDeleteable={false}
isEditable={false}
@ -123,7 +123,7 @@ const TelemetryServiceTable: FunctionComponent<ComponentProps> = (
},
title: "Name",
type: FieldType.Element,
getElement: (service: TelemetryService): ReactElement => {
getElement: (service: Service): ReactElement => {
return (
<Fragment>
<TelemetryServiceElement telemetryService={service} />
@ -148,7 +148,7 @@ const TelemetryServiceTable: FunctionComponent<ComponentProps> = (
title: "Labels",
type: FieldType.EntityArray,
getElement: (item: TelemetryService): ReactElement => {
getElement: (item: Service): ReactElement => {
return <LabelsElement labels={item["labels"] || []} />;
},
},

View file

@ -1,7 +1,7 @@
import DashboardLogsViewer from "../Logs/LogsViewer";
import SpanStatusElement from "../Span/SpanStatusElement";
import SpanViewer from "../Span/SpanViewer";
import TelemetryServiceElement from "..//TelemetryService/TelemetryServiceElement";
import ServiceElement from "..//Service/ServiceElement";
import ProjectUtil from "Common/UI/Utils/Project";
import SpanUtil, {
DivisibilityFactor,
@ -30,7 +30,7 @@ import ListResult from "Common/Types/BaseDatabase/ListResult";
import Select from "Common/Types/BaseDatabase/Select";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import Span, { SpanStatus } from "Common/Models/AnalyticsModels/Span";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const INITIAL_SPAN_FETCH_SIZE: number = 500;
@ -53,8 +53,8 @@ type GetBarTooltipFunction = (data: BarTooltipFunctionProps) => ReactElement;
const TraceExplorer: FunctionComponent<ComponentProps> = (
props: ComponentProps,
): ReactElement => {
const [telemetryServices, setTelemetryServices] = React.useState<
TelemetryService[]
const [telemetryServices, setServices] = React.useState<
Service[]
>([]);
const [selectedSpans, setSelectedSpans] = React.useState<string[]>([]);
@ -106,16 +106,16 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
[],
);
const fetchTelemetryServices: PromiseVoidFunction =
const fetchServices: PromiseVoidFunction =
React.useCallback(async (): Promise<void> => {
const telemetryServicesResult: ListResult<TelemetryService> =
await ModelAPI.getList<TelemetryService>({
const telemetryServicesResult: ListResult<Service> =
await ModelAPI.getList<Service>({
query: {
projectId: ProjectUtil.getCurrentProjectId()!,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
modelType: TelemetryService,
modelType: Service,
sort: {
name: SortOrder.Ascending,
},
@ -126,7 +126,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
},
});
setTelemetryServices(telemetryServicesResult.data);
setServices(telemetryServicesResult.data);
}, []);
type FetchSpansParams = {
@ -243,7 +243,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
try {
await Promise.all([
fetchTelemetryServices(),
fetchServices(),
fetchSpans({
limit: INITIAL_SPAN_FETCH_SIZE,
skip: 0,
@ -253,7 +253,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
} catch (err) {
setError(API.getFriendlyMessage(err));
}
}, [fetchTelemetryServices, fetchSpans]);
}, [fetchServices, fetchSpans]);
const getBarTooltip: GetBarTooltipFunction = (
data: BarTooltipFunctionProps,
@ -397,19 +397,19 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
};
type GetRowDescriptionFunction = (data: {
telemetryService: TelemetryService;
telemetryService: Service;
span: Span;
}) => ReactElement;
const getRowDescription: GetRowDescriptionFunction = (data: {
telemetryService: TelemetryService;
telemetryService: Service;
span: Span;
}): ReactElement => {
const { telemetryService } = data;
return (
<div className="flex space-x-5">
<TelemetryServiceElement
<ServiceElement
telemetryService={telemetryService}
telemetryServiceNameClassName="mt-0.5"
/>
@ -433,8 +433,8 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
return [];
}
const telemetryService: TelemetryService | undefined =
telemetryServices.find((service: TelemetryService) => {
const telemetryService: Service | undefined =
telemetryServices.find((service: Service) => {
return service._id?.toString() === rootSpan.serviceId?.toString();
});
@ -600,7 +600,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
* Derived values for summary / filtering
* Services involved in this trace only
*/
const servicesInTrace: TelemetryService[] = React.useMemo(() => {
const servicesInTrace: Service[] = React.useMemo(() => {
if (spans.length === 0) {
return [];
}
@ -613,7 +613,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
return s.serviceId!.toString();
}),
);
return telemetryServices.filter((svc: TelemetryService) => {
return telemetryServices.filter((svc: Service) => {
return serviceIdsInTrace.has(svc._id!.toString());
});
}, [telemetryServices, spans]);
@ -643,7 +643,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
return;
}
const validIds: Set<string> = new Set(
servicesInTrace.map((s: TelemetryService) => {
servicesInTrace.map((s: Service) => {
return s._id!.toString();
}),
);
@ -810,8 +810,8 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
*/
if (allRows.length === 1 && displaySpans.length > 10) {
allRows = displaySpans.map((span: Span) => {
const telemetryService: TelemetryService | undefined =
telemetryServices.find((service: TelemetryService) => {
const telemetryService: Service | undefined =
telemetryServices.find((service: Service) => {
return service._id?.toString() === span.serviceId?.toString();
});
return {
@ -909,7 +909,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
) : (
<></>
)}
{servicesInTrace.map((service: TelemetryService) => {
{servicesInTrace.map((service: Service) => {
const id: string = service._id!.toString();
const isSelected: boolean = selectedServiceIds.includes(id);
const counts: { total: number; error: number } | undefined =
@ -1278,7 +1278,7 @@ const TraceExplorer: FunctionComponent<ComponentProps> = (
setSelectedSpans([]);
}}
telemetryService={
telemetryServices.find((service: TelemetryService) => {
telemetryServices.find((service: Service) => {
const selectedSpan: Span | undefined = spans.find(
(span: Span) => {
return span.spanId?.toString() === selectedSpans[0]!;

View file

@ -32,9 +32,9 @@ import Query from "Common/Types/BaseDatabase/Query";
import SpanUtil from "../../Utils/SpanUtil";
import TraceElement from "./TraceElement";
import ListResult from "Common/Types/BaseDatabase/ListResult";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import TelemetryServiceElement from "../TelemetryService/TelemetryServiceElement";
import ServiceElement from "../Service/ServiceElement";
import Tabs from "Common/UI/Components/Tabs/Tabs";
import { Tab } from "Common/UI/Components/Tabs/Tab";
import IsNull from "Common/Types/BaseDatabase/IsNull";
@ -65,8 +65,8 @@ const TraceTable: FunctionComponent<ComponentProps> = (
props.spanQuery || null,
);
const [telemetryServices, setTelemetryServices] = React.useState<
Array<TelemetryService>
const [telemetryServices, setServices] = React.useState<
Array<Service>
>([]);
const [areAdvancedFiltersVisible, setAreAdvancedFiltersVisible] =
@ -143,15 +143,15 @@ const TraceTable: FunctionComponent<ComponentProps> = (
}
}, [props.spanQuery]);
const loadTelemetryServices: PromiseVoidFunction =
const loadServices: PromiseVoidFunction =
async (): Promise<void> => {
try {
setIsPageLoading(true);
setPageError("");
const telemetryServicesResponse: ListResult<TelemetryService> =
const telemetryServicesResponse: ListResult<Service> =
await ModelAPI.getList({
modelType: TelemetryService,
modelType: Service,
query: {
projectId: ProjectUtil.getCurrentProjectId()!,
},
@ -166,7 +166,7 @@ const TraceTable: FunctionComponent<ComponentProps> = (
},
});
setTelemetryServices(telemetryServicesResponse.data || []);
setServices(telemetryServicesResponse.data || []);
} catch (err) {
setPageError(API.getFriendlyErrorMessage(err as Error));
} finally {
@ -213,7 +213,7 @@ const TraceTable: FunctionComponent<ComponentProps> = (
};
useEffect(() => {
loadTelemetryServices().catch((err: Error) => {
loadServices().catch((err: Error) => {
setPageError(API.getFriendlyErrorMessage(err as Error));
});
}, []);
@ -255,7 +255,7 @@ const TraceTable: FunctionComponent<ComponentProps> = (
<ErrorMessage
message={`We couldn't load telemetry services. ${pageError}`}
onRefreshClick={() => {
void loadTelemetryServices();
void loadServices();
}}
/>
</div>
@ -318,7 +318,7 @@ const TraceTable: FunctionComponent<ComponentProps> = (
},
type: FieldType.MultiSelectDropdown,
filterDropdownOptions: telemetryServices.map(
(service: TelemetryService) => {
(service: Service) => {
return {
label: service.name!,
value: service.id!.toString(),
@ -425,8 +425,8 @@ const TraceTable: FunctionComponent<ComponentProps> = (
title: "Service",
type: FieldType.Element,
getElement: (span: Span): ReactElement => {
const telemetryService: TelemetryService | undefined =
telemetryServices.find((service: TelemetryService) => {
const telemetryService: Service | undefined =
telemetryServices.find((service: Service) => {
return (
service.id?.toString() === span.serviceId?.toString()
);
@ -438,7 +438,7 @@ const TraceTable: FunctionComponent<ComponentProps> = (
return (
<Fragment>
<TelemetryServiceElement
<ServiceElement
telemetryService={telemetryService}
/>
</Fragment>

View file

@ -2,87 +2,16 @@ import DashboardLogsViewer from "../../../Components/Logs/LogsViewer";
import PageComponentProps from "../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import ServiceTelemetryService from "Common/Models/DatabaseModels/ServiceTelemetryService";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import ListResult from "Common/Types/BaseDatabase/ListResult";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import API from "Common/UI/Utils/API/API";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceLogs: FunctionComponent<PageComponentProps> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [telemetryServiceIds, setTelemetryServiceIds] =
useState<Array<ObjectID> | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const fetchTelemetryServices: PromiseVoidFunction =
async (): Promise<void> => {
try {
setIsLoading(true);
const response: ListResult<ServiceTelemetryService> =
await ModelAPI.getList<ServiceTelemetryService>({
modelType: ServiceTelemetryService,
query: {
serviceId: modelId,
},
select: {
telemetryServiceId: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
sort: {},
});
const ids: ObjectID[] = response.data.map(
(serviceTelemetryService: ServiceTelemetryService) => {
return serviceTelemetryService.telemetryServiceId!;
},
);
setTelemetryServiceIds(ids);
setIsLoading(false);
} catch (err) {
setIsLoading(false);
setError(API.getFriendlyMessage(err));
}
};
useEffect(() => {
fetchTelemetryServices().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
if (error) {
return <ErrorMessage message={error} />;
}
if (isLoading || telemetryServiceIds === null) {
return <PageLoader isVisible={true} />;
}
if (telemetryServiceIds.length === 0) {
return (
<ErrorMessage message="Assign telemetry services to this service to view logs." />
);
}
return (
<Fragment>
<DashboardLogsViewer
id="service-logs"
telemetryServiceIds={telemetryServiceIds}
serviceIds={[modelId]}
showFilters={true}
enableRealtime={true}
limit={100}

View file

@ -2,86 +2,16 @@ import MetricsTable from "../../../Components/Metrics/MetricsTable";
import PageComponentProps from "../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import ServiceTelemetryService from "Common/Models/DatabaseModels/ServiceTelemetryService";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import ListResult from "Common/Types/BaseDatabase/ListResult";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import API from "Common/UI/Utils/API/API";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceMetrics: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [telemetryServiceIds, setTelemetryServiceIds] =
useState<Array<ObjectID> | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const fetchTelemetryServices: PromiseVoidFunction =
async (): Promise<void> => {
try {
setIsLoading(true);
const response: ListResult<ServiceTelemetryService> =
await ModelAPI.getList<ServiceTelemetryService>({
modelType: ServiceTelemetryService,
query: {
serviceId: modelId,
},
select: {
telemetryServiceId: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
sort: {},
});
const ids: ObjectID[] = response.data.map(
(serviceTelemetryService: ServiceTelemetryService) => {
return serviceTelemetryService.telemetryServiceId!;
},
);
setTelemetryServiceIds(ids);
setIsLoading(false);
} catch (err) {
setIsLoading(false);
setError(API.getFriendlyMessage(err));
}
};
useEffect(() => {
fetchTelemetryServices().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
if (error) {
return <ErrorMessage message={error} />;
}
if (isLoading || telemetryServiceIds === null) {
return <PageLoader isVisible={true} />;
}
if (telemetryServiceIds.length === 0) {
return (
<ErrorMessage message="Assign telemetry services to this service to view metrics." />
);
}
return (
<Fragment>
<MetricsTable telemetryServiceIds={telemetryServiceIds} />
<MetricsTable serviceIds={[modelId]} />
</Fragment>
);
};

View file

@ -64,17 +64,6 @@ const DashboardSideMenu: FunctionComponent<ComponentProps> = (
icon={IconProp.AltGlobe}
/>
<SideMenuItem
link={{
title: "Telemetry Services",
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.SERVICE_VIEW_TELEMETRY_SERVICES] as Route,
{ modelId: props.modelId },
),
}}
icon={IconProp.Cube}
/>
<SideMenuItem
link={{
title: "Code Repositories",

View file

@ -1,252 +0,0 @@
import PageComponentProps from "../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import ServiceTelemetryService from "Common/Models/DatabaseModels/ServiceTelemetryService";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import TelemetryServicesTable from "../../../Components/TelemetryService/TelemetryServiceTable";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import ListResult from "Common/Types/BaseDatabase/ListResult";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import API from "Common/UI/Utils/API/API";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import Includes from "Common/Types/BaseDatabase/Includes";
import { ButtonStyleType } from "Common/UI/Components/Button/Button";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import ConfirmModal from "Common/UI/Components/Modal/ConfirmModal";
import IconProp from "Common/Types/Icon/IconProp";
import ModelFormModal from "Common/UI/Components/ModelFormModal/ModelFormModal";
import { FormType } from "Common/UI/Components/Forms/ModelForm";
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
import ProjectUtil from "Common/UI/Utils/Project";
const ServiceTelemetryServices: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [telemetryServiceIds, setTelemetryServiceIds] =
useState<Array<ObjectID> | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const [showUnassignModal, setShowUnassignModal] = useState<boolean>(false);
const [selectedTelemetryService, setSelectedTelemetryService] =
useState<TelemetryService | null>(null);
const [isUnassignLoading, setIsUnassignLoading] = useState<boolean>(false);
const [unassignError, setUnassignError] = useState<string | null>(null);
const [showModelForm, setShowModelForm] = useState<boolean>(false);
const fetchTelemetryServicesInService: PromiseVoidFunction =
async (): Promise<void> => {
// Fetch TelemetryServiceStatus by ID
try {
setIsLoading(true);
const serviceTelemetryServices: ListResult<ServiceTelemetryService> =
await ModelAPI.getList<ServiceTelemetryService>({
modelType: ServiceTelemetryService,
query: {
serviceId: modelId,
},
select: {
telemetryServiceId: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
sort: {},
});
const telemetryServiceIds: ObjectID[] =
serviceTelemetryServices.data.map(
(serviceTelemetryService: ServiceTelemetryService) => {
return serviceTelemetryService.telemetryServiceId!;
},
);
setTelemetryServiceIds(telemetryServiceIds);
setIsLoading(false);
} catch (err) {
setIsLoading(false);
setError(API.getFriendlyMessage(err));
}
};
useEffect(() => {
fetchTelemetryServicesInService().catch((error: Error) => {
setError(API.getFriendlyMessage(error));
});
}, []);
if (error) {
return <ErrorMessage message={error} />;
}
if (isLoading) {
return <PageLoader isVisible={true} />;
}
return (
<Fragment>
<TelemetryServicesTable
disableCreate={true}
query={{
_id: new Includes(telemetryServiceIds || []),
}}
actionButtons={[
{
buttonStyleType: ButtonStyleType.DANGER_OUTLINE,
title: "Unassign",
onClick: (
telemetryService: TelemetryService,
onCompleteAction: VoidFunction,
) => {
setSelectedTelemetryService(telemetryService);
setShowUnassignModal(true);
onCompleteAction();
},
},
]}
cardButtons={[
{
title: "Assign Telemetry Service",
buttonStyle: ButtonStyleType.NORMAL,
onClick: () => {
setShowModelForm(true);
},
icon: IconProp.Add,
isLoading: false,
},
]}
title={"Telemetry Services for this Service"}
description="List of Telemetry Services that are assigned to this service."
noItemsMessage={"No Telemetry Services added to this service."}
/>
{showUnassignModal ? (
<ConfirmModal
title={`Unassign TelemetryService from Service`}
description={
<div>
Are you sure you want to unassign the telemetryService from this
service?
</div>
}
error={unassignError || ""}
isLoading={isUnassignLoading}
submitButtonType={ButtonStyleType.DANGER}
submitButtonText={"Unassign"}
onClose={() => {
setShowUnassignModal(false);
setUnassignError(null);
setSelectedTelemetryService(null);
}}
onSubmit={async () => {
try {
setIsUnassignLoading(true);
// get ServiceTelemetryServiceId
const serviceTelemetryService: ListResult<ServiceTelemetryService> =
await ModelAPI.getList<ServiceTelemetryService>({
modelType: ServiceTelemetryService,
query: {
telemetryServiceId: selectedTelemetryService!.id!,
serviceId: modelId!,
},
select: {
_id: true,
},
limit: 1,
skip: 0,
sort: {},
});
if (serviceTelemetryService.data.length === 0) {
setUnassignError("Service Telemetry Service not found");
setIsUnassignLoading(false);
return;
}
await ModelAPI.deleteItem<ServiceTelemetryService>({
modelType: ServiceTelemetryService,
id: serviceTelemetryService.data[0]!.id!,
});
setIsUnassignLoading(false);
setSelectedTelemetryService(null);
setShowUnassignModal(false);
setUnassignError(null);
fetchTelemetryServicesInService().catch((error: Error) => {
setError(API.getFriendlyMessage(error));
});
} catch (err) {
setIsUnassignLoading(false);
setUnassignError(API.getFriendlyMessage(err));
}
}}
/>
) : (
<></>
)}
{showModelForm ? (
<ModelFormModal<ServiceTelemetryService>
modelType={ServiceTelemetryService}
name="Assign Telemetry Service to Service"
title="Assign Telemetry Service to Service"
description="Assign a Telemetry Service to this service. This is helpful for determining the health of the service."
onClose={() => {
setShowModelForm(false);
}}
submitButtonText="Assign"
onSuccess={() => {
setShowModelForm(false);
fetchTelemetryServicesInService().catch((error: Error) => {
setError(API.getFriendlyMessage(error));
});
}}
onBeforeCreate={(
serviceTelemetryService: ServiceTelemetryService,
) => {
serviceTelemetryService.serviceId = modelId;
serviceTelemetryService.projectId =
ProjectUtil.getCurrentProjectId()!;
return Promise.resolve(serviceTelemetryService);
}}
formProps={{
name: "Assign Telemetry Service",
modelType: ServiceTelemetryService,
id: "create-service-telemetryService",
fields: [
{
field: {
telemetryService: true,
},
title: "Select TelemetryService",
description:
"Select Telemetry Service to assign to this service.",
fieldType: FormFieldSchemaType.Dropdown,
dropdownModal: {
type: TelemetryService,
labelField: "name",
valueField: "_id",
},
required: true,
placeholder: "Select Telemetry Service",
},
],
formType: FormType.Create,
}}
/>
) : (
<></>
)}
</Fragment>
);
};
export default ServiceTelemetryServices;

View file

@ -2,22 +2,7 @@ import TraceTable from "../../../Components/Traces/TraceTable";
import PageComponentProps from "../../PageComponentProps";
import ObjectID from "Common/Types/ObjectID";
import Navigation from "Common/UI/Utils/Navigation";
import React, {
Fragment,
FunctionComponent,
ReactElement,
useEffect,
useState,
} from "react";
import ServiceTelemetryService from "Common/Models/DatabaseModels/ServiceTelemetryService";
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
import ListResult from "Common/Types/BaseDatabase/ListResult";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import API from "Common/UI/Utils/API/API";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import Includes from "Common/Types/BaseDatabase/Includes";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
import Query from "Common/Types/BaseDatabase/Query";
import Span from "Common/Models/AnalyticsModels/Span";
@ -26,65 +11,8 @@ const ServiceTraces: FunctionComponent<
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [telemetryServiceIds, setTelemetryServiceIds] =
useState<Array<ObjectID> | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const fetchTelemetryServices: PromiseVoidFunction =
async (): Promise<void> => {
try {
setIsLoading(true);
const response: ListResult<ServiceTelemetryService> =
await ModelAPI.getList<ServiceTelemetryService>({
modelType: ServiceTelemetryService,
query: {
serviceId: modelId,
},
select: {
telemetryServiceId: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
sort: {},
});
const ids: ObjectID[] = response.data.map(
(serviceTelemetryService: ServiceTelemetryService) => {
return serviceTelemetryService.telemetryServiceId!;
},
);
setTelemetryServiceIds(ids);
setIsLoading(false);
} catch (err) {
setIsLoading(false);
setError(API.getFriendlyMessage(err));
}
};
useEffect(() => {
fetchTelemetryServices().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
if (error) {
return <ErrorMessage message={error} />;
}
if (isLoading || telemetryServiceIds === null) {
return <PageLoader isVisible={true} />;
}
if (telemetryServiceIds.length === 0) {
return (
<ErrorMessage message="Assign telemetry services to this service to view traces." />
);
}
const spanQuery: Query<Span> = {
serviceId: new Includes(telemetryServiceIds),
serviceId: modelId,
};
return (

View file

@ -1,4 +1,4 @@
import TelemetryServiceElement from "../../Components/TelemetryService/TelemetryServiceElement";
import ServiceElement from "../../Components/Service/ServiceElement";
import ProjectUtil from "Common/UI/Utils/Project";
import PageComponentProps from "../PageComponentProps";
import Currency from "Common/Types/Currency";
@ -9,7 +9,7 @@ import { DropdownOption } from "Common/UI/Components/Dropdown/Dropdown";
import ModelTable from "Common/UI/Components/ModelTable/ModelTable";
import FieldType from "Common/UI/Components/Types/FieldType";
import DropdownUtil from "Common/UI/Utils/Dropdown";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import TelemetryUsageBilling from "Common/Models/DatabaseModels/TelemetryUsageBilling";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
@ -67,7 +67,7 @@ const Settings: FunctionComponent<ComponentProps> = (
},
title: "Telemetry Service",
type: FieldType.Entity,
filterEntityType: TelemetryService,
filterEntityType: Service,
filterQuery: {
projectId: ProjectUtil.getCurrentProjectId()!,
},
@ -118,9 +118,9 @@ const Settings: FunctionComponent<ComponentProps> = (
type: FieldType.Element,
getElement: (item: TelemetryUsageBilling) => {
return (
<TelemetryServiceElement
<ServiceElement
telemetryService={
item["telemetryService"] as TelemetryService
item["telemetryService"] as Service
}
/>
);

View file

@ -18,7 +18,7 @@ const Services: FunctionComponent<PageComponentProps> = (
return (
<DashboardLogsViewer
showFilters={true}
telemetryServiceIds={[]}
serviceIds={[]}
limit={100} // Limit the number of logs to 100 by default
enableRealtime={true}
id="logs"

View file

@ -5,7 +5,7 @@ import Route from "Common/Types/API/Route";
import ObjectID from "Common/Types/ObjectID";
import ModelDelete from "Common/UI/Components/ModelDelete/ModelDelete";
import Navigation from "Common/UI/Utils/Navigation";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
@ -16,7 +16,7 @@ const ServiceDelete: FunctionComponent<
return (
<Fragment>
<ModelDelete
modelType={TelemetryService}
modelType={Service}
modelId={modelId}
onDeleteSuccess={() => {
Navigation.navigate(

View file

@ -6,7 +6,7 @@ import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import FieldType from "Common/UI/Components/Types/FieldType";
import Navigation from "Common/UI/Utils/Navigation";
import Label from "Common/Models/DatabaseModels/Label";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
@ -17,7 +17,7 @@ const ServiceDelete: FunctionComponent<
return (
<Fragment>
{/* Service View */}
<CardModelDetail<TelemetryService>
<CardModelDetail<Service>
name="Service Details"
formSteps={[
{
@ -78,7 +78,7 @@ const ServiceDelete: FunctionComponent<
]}
modelDetailProps={{
showDetailsInNumberOfColumns: 2,
modelType: TelemetryService,
modelType: Service,
id: "model-detail-services",
fields: [
{
@ -103,7 +103,7 @@ const ServiceDelete: FunctionComponent<
},
title: "Labels",
fieldType: FieldType.Element,
getElement: (item: TelemetryService): ReactElement => {
getElement: (item: Service): ReactElement => {
return <LabelsElement labels={item["labels"] || []} />;
},
},

View file

@ -5,11 +5,11 @@ import SideMenu from "./SideMenu";
import ObjectID from "Common/Types/ObjectID";
import ModelPage from "Common/UI/Components/Page/ModelPage";
import Navigation from "Common/UI/Utils/Navigation";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { FunctionComponent, ReactElement } from "react";
import { Outlet, useParams } from "react-router-dom";
const TelemetryServiceViewLayout: FunctionComponent<
const ServiceViewLayout: FunctionComponent<
PageComponentProps
> = (): ReactElement => {
const { id } = useParams();
@ -18,7 +18,7 @@ const TelemetryServiceViewLayout: FunctionComponent<
return (
<ModelPage
title="Service"
modelType={TelemetryService}
modelType={Service}
modelId={modelId}
modelNameField="name"
breadcrumbLinks={getTelemetryBreadcrumbs(path)}
@ -29,4 +29,4 @@ const TelemetryServiceViewLayout: FunctionComponent<
);
};
export default TelemetryServiceViewLayout;
export default ServiceViewLayout;

View file

@ -13,7 +13,7 @@ const ServiceDelete: FunctionComponent<
<Fragment>
<DashboardLogsViewer
showFilters={true}
telemetryServiceIds={[modelId]}
serviceIds={[modelId]}
enableRealtime={true}
limit={100}
id="logs"

View file

@ -7,7 +7,7 @@ import React, {
useEffect,
useState,
} from "react";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
import PageLoader from "Common/UI/Components/Loader/PageLoader";
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
@ -20,38 +20,38 @@ const MetricsTablePage: FunctionComponent<
> = (): ReactElement => {
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
const [telemetryService, setTelemetryService] =
useState<TelemetryService | null>(null);
const [service, setService] =
useState<Service | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [error, setError] = useState<string>("");
useEffect(() => {
fetchTelemetryService().catch((err: Error) => {
fetchService().catch((err: Error) => {
setError(API.getFriendlyMessage(err));
});
}, []);
const fetchTelemetryService: PromiseVoidFunction =
const fetchService: PromiseVoidFunction =
async (): Promise<void> => {
try {
setIsLoading(true);
const telemetryService: TelemetryService | null =
const service: Service | null =
await ModelAPI.getItem({
modelType: TelemetryService,
modelType: Service,
id: modelId,
select: {
name: true,
},
});
if (!telemetryService) {
if (!service) {
setIsLoading(false);
setError("Telemetry Service not found.");
setError("Service not found.");
return;
}
setTelemetryService(telemetryService);
setService(service);
setIsLoading(false);
} catch (err) {
setIsLoading(false);
@ -67,11 +67,11 @@ const MetricsTablePage: FunctionComponent<
return <PageLoader isVisible={true} />;
}
if (!telemetryService) {
return <ErrorMessage message="Telemetry Service not found." />;
if (!service) {
return <ErrorMessage message="Service not found." />;
}
return <MetricsTable telemetryServiceIds={[telemetryService.id!]} />;
return <MetricsTable serviceIds={[service.id!]} />;
};
export default MetricsTablePage;

View file

@ -4,7 +4,7 @@ import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchem
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
import FieldType from "Common/UI/Components/Types/FieldType";
import Navigation from "Common/UI/Utils/Navigation";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import React, { Fragment, FunctionComponent, ReactElement } from "react";
const ServiceDelete: FunctionComponent<
@ -37,7 +37,7 @@ const ServiceDelete: FunctionComponent<
},
]}
modelDetailProps={{
modelType: TelemetryService,
modelType: Service,
id: "model-detail-project",
fields: [
{
@ -75,7 +75,7 @@ const ServiceDelete: FunctionComponent<
},
]}
modelDetailProps={{
modelType: TelemetryService,
modelType: Service,
id: "model-detail-project",
fields: [
{

View file

@ -48,12 +48,6 @@ const ServiceViewAlerts: LazyExoticComponent<
return import("../Pages/Service/View/Alerts");
});
const ServiceViewTelemetryServices: LazyExoticComponent<
FunctionComponent<ComponentProps>
> = lazy(() => {
return import("../Pages/Service/View/TelemetryServices");
});
const ServiceViewLogs: LazyExoticComponent<FunctionComponent<ComponentProps>> =
lazy(() => {
return import("../Pages/Service/View/Logs");
@ -207,22 +201,6 @@ const ServiceRoutes: FunctionComponent<ComponentProps> = (
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(
PageMap.SERVICE_VIEW_TELEMETRY_SERVICES,
)}
element={
<Suspense fallback={Loader}>
<ServiceViewTelemetryServices
{...props}
pageRoute={
RouteMap[PageMap.SERVICE_VIEW_TELEMETRY_SERVICES] as Route
}
/>
</Suspense>
}
/>
<PageRoute
path={RouteUtil.getLastPathForKey(PageMap.SERVICE_VIEW_LOGS)}
element={

View file

@ -76,12 +76,6 @@ export function getServiceBreadcrumbs(path: string): Array<Link> | undefined {
"View Service",
"Metrics",
]),
...BuildBreadcrumbLinksByTitles(PageMap.SERVICE_VIEW_TELEMETRY_SERVICES, [
"Project",
"Services",
"View Service",
"Telemetry",
]),
...BuildBreadcrumbLinksByTitles(PageMap.SERVICE_VIEW_CODE_REPOSITORIES, [
"Project",
"Services",

View file

@ -154,7 +154,6 @@ enum PageMap {
SERVICE_VIEW_LOGS = "SERVICE_VIEW_LOGS",
SERVICE_VIEW_TRACES = "SERVICE_VIEW_TRACES",
SERVICE_VIEW_METRICS = "SERVICE_VIEW_METRICS",
SERVICE_VIEW_TELEMETRY_SERVICES = "SERVICE_VIEW_TELEMETRY_SERVICES",
SERVICE_VIEW_OWNERS = "SERVICE_VIEW_OWNERS",
SERVICE_VIEW_DEPENDENCIES = "SERVICE_VIEW_DEPENDENCIES",
SERVICE_VIEW_CODE_REPOSITORIES = "SERVICE_VIEW_CODE_REPOSITORIES",

View file

@ -43,7 +43,6 @@ export const ServiceRoutePath: Dictionary<string> = {
[PageMap.SERVICE_VIEW_LOGS]: `${RouteParams.ModelID}/logs`,
[PageMap.SERVICE_VIEW_TRACES]: `${RouteParams.ModelID}/traces`,
[PageMap.SERVICE_VIEW_METRICS]: `${RouteParams.ModelID}/metrics`,
[PageMap.SERVICE_VIEW_TELEMETRY_SERVICES]: `${RouteParams.ModelID}/telemetry-service`,
[PageMap.SERVICE_VIEW_CODE_REPOSITORIES]: `${RouteParams.ModelID}/code-repositories`,
};
@ -937,12 +936,6 @@ const RouteMap: Dictionary<Route> = {
}`,
),
[PageMap.SERVICE_VIEW_TELEMETRY_SERVICES]: new Route(
`/dashboard/${RouteParams.ProjectID}/service/${
ServiceRoutePath[PageMap.SERVICE_VIEW_TELEMETRY_SERVICES]
}`,
),
[PageMap.SERVICE_VIEW_CODE_REPOSITORIES]: new Route(
`/dashboard/${RouteParams.ProjectID}/service/${
ServiceRoutePath[PageMap.SERVICE_VIEW_CODE_REPOSITORIES]

View file

@ -2,7 +2,7 @@ import { Black } from "Common/Types/BrandColors";
import Color from "Common/Types/Color";
import OneUptimeDate from "Common/Types/Date";
import Span, { SpanKind, SpanStatus } from "Common/Models/AnalyticsModels/Span";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import { DropdownOption } from "Common/UI/Components/Dropdown/Dropdown";
import DropdownUtil from "Common/UI/Utils/Dropdown";
@ -168,12 +168,12 @@ export default class SpanUtil {
public static getGanttChartBarColor(data: {
span: Span;
telemetryServices: Array<TelemetryService>;
telemetryServices: Array<Service>;
}): {
barColor: Color;
} {
const service: TelemetryService | undefined = data.telemetryServices.find(
(service: TelemetryService) => {
const service: Service | undefined = data.telemetryServices.find(
(service: Service) => {
return service.id?.toString() === data.span.serviceId?.toString();
},
);

View file

@ -23,7 +23,7 @@ import { JSONArray, JSONObject } from "Common/Types/JSON";
import logger from "Common/Server/Utils/Logger";
import CaptureSpan from "Common/Server/Utils/Telemetry/CaptureSpan";
import MetricType from "Common/Models/DatabaseModels/MetricType";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import MetricsQueueService from "./Queue/MetricsQueueService";
import OtelIngestBaseService from "./OtelIngestBaseService";
import { TELEMETRY_METRIC_FLUSH_BATCH_SIZE } from "../Config";
@ -206,15 +206,12 @@ export default class OtelMetricsIngestService extends OtelIngestBaseService {
metricNameServiceNameMap[metricName]!.description =
metricDescription;
metricNameServiceNameMap[metricName]!.unit = metricUnit;
metricNameServiceNameMap[metricName]!.telemetryServices =
[];
metricNameServiceNameMap[metricName]!.services = [];
}
if (
metricNameServiceNameMap[
metricName
]!.telemetryServices!.filter(
(service: TelemetryService) => {
metricNameServiceNameMap[metricName]!.services!.filter(
(service: Service) => {
return (
service.id?.toString() ===
serviceMetadata.serviceId!.toString()
@ -222,12 +219,11 @@ export default class OtelMetricsIngestService extends OtelIngestBaseService {
},
).length === 0
) {
const telemetryService: TelemetryService =
new TelemetryService();
telemetryService.id = serviceMetadata.serviceId!;
metricNameServiceNameMap[
metricName
]!.telemetryServices!.push(telemetryService);
const newService: Service = new Service();
newService.id = serviceMetadata.serviceId!;
metricNameServiceNameMap[metricName]!.services!.push(
newService,
);
}
}

View file

@ -7,10 +7,10 @@ import ProjectService from "Common/Server/Services/ProjectService";
import LogService from "Common/Server/Services/LogService";
import MetricService from "Common/Server/Services/MetricService";
import SpanService from "Common/Server/Services/SpanService";
import TelemetryServiceService from "Common/Server/Services/TelemetryServiceService";
import ServiceService from "Common/Server/Services/ServiceService";
import logger from "Common/Server/Utils/Logger";
import QueryHelper from "Common/Server/Types/AnalyticsDatabase/QueryHelper";
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
import Service from "Common/Models/DatabaseModels/Service";
import Project from "Common/Models/DatabaseModels/Project";
import { ServiceType } from "Common/Models/AnalyticsModels/Metric";
@ -47,24 +47,23 @@ RunCron(
continue;
}
const telemetryServices: Array<TelemetryService> =
await TelemetryServiceService.findBy({
query: {
projectId: project.id,
},
limit: LIMIT_MAX,
skip: 0,
select: {
retainTelemetryDataForDays: true,
projectId: true,
_id: true,
},
props: {
isRoot: true,
},
});
const services: Array<Service> = await ServiceService.findBy({
query: {
projectId: project.id,
},
limit: LIMIT_MAX,
skip: 0,
select: {
retainTelemetryDataForDays: true,
projectId: true,
_id: true,
},
props: {
isRoot: true,
},
});
for (const service of telemetryServices) {
for (const service of services) {
try {
if (!service || !service.id) {
continue;