mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
Update usageCount and totalCostInUSD to use Decimal type
This commit is contained in:
parent
03a503b080
commit
018d3b7fcd
77
Common/Types/Decimal.ts
Normal file
77
Common/Types/Decimal.ts
Normal file
@ -0,0 +1,77 @@
|
||||
// This is for Object ID for all the things in our database.
|
||||
import { FindOperator } from 'typeorm';
|
||||
import DatabaseProperty from './Database/DatabaseProperty';
|
||||
import { JSONObject, ObjectType } from './JSON';
|
||||
import BadDataException from './Exception/BadDataException';
|
||||
|
||||
export default class Decimal extends DatabaseProperty {
|
||||
|
||||
private _value: number = 0;
|
||||
public get value(): number {
|
||||
return this._value;
|
||||
}
|
||||
public set value(v: number) {
|
||||
this._value = v;
|
||||
}
|
||||
|
||||
public constructor(value: number | Decimal | string) {
|
||||
super();
|
||||
|
||||
if (typeof value === 'string') {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
if (value instanceof Decimal) {
|
||||
value = value.value;
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public equals(other: Decimal): boolean {
|
||||
return this.value.toString() === other.value.toString();
|
||||
}
|
||||
|
||||
public override toString(): string {
|
||||
return this.value.toString();
|
||||
}
|
||||
|
||||
|
||||
protected static override toDatabase(
|
||||
value: Decimal | FindOperator<Decimal>
|
||||
): string | null {
|
||||
if (value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override toJSON(): JSONObject {
|
||||
return {
|
||||
_type: ObjectType.Decimal,
|
||||
value: (this as Decimal).toString(),
|
||||
};
|
||||
}
|
||||
|
||||
public static override fromJSON(json: JSONObject): Decimal {
|
||||
if (json['_type'] === ObjectType.Decimal) {
|
||||
return new Decimal((json['value'] as number) || 0);
|
||||
}
|
||||
|
||||
throw new BadDataException('Invalid JSON: ' + JSON.stringify(json));
|
||||
}
|
||||
|
||||
protected static override fromDatabase(_value: number): Decimal | null {
|
||||
if (_value) {
|
||||
return new Decimal(_value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static fromString(value: string): Decimal {
|
||||
return new Decimal(value);
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import StartAndEndTime from './Time/StartAndEndTime';
|
||||
|
||||
export enum ObjectType {
|
||||
ObjectID = 'ObjectID',
|
||||
Decimal = 'Decimal',
|
||||
Name = 'Name',
|
||||
EqualToOrNull = 'EqualToOrNull',
|
||||
MonitorSteps = 'MonitorSteps',
|
||||
|
@ -9,6 +9,7 @@ import SortOrder from 'Common/Types/BaseDatabase/SortOrder';
|
||||
import { MeteredPlanUtil } from '../Types/Billing/MeteredPlan/AllMeteredPlans';
|
||||
import MeteredPlan from 'Common/Types/Billing/MeteredPlan';
|
||||
import ServerMeteredPlan from '../Types/Billing/MeteredPlan/ServerMeteredPlan';
|
||||
import Decimal from 'Common/Types/Decimal';
|
||||
|
||||
export class Service extends DatabaseService<Model> {
|
||||
public constructor(postgresDatabase?: PostgresDatabase) {
|
||||
@ -94,10 +95,10 @@ export class Service extends DatabaseService<Model> {
|
||||
id: usageBilling.id,
|
||||
data: {
|
||||
usageCount:
|
||||
(usageBilling.usageCount || 0) + data.usageCount,
|
||||
totalCostInUSD:
|
||||
(usageBilling.totalCostInUSD || 0) +
|
||||
totalCostOfThisOperationInUSD,
|
||||
new Decimal((usageBilling.usageCount?.value || 0) + data.usageCount),
|
||||
totalCostInUSD:new Decimal(
|
||||
(usageBilling.totalCostInUSD?.value || 0) +
|
||||
totalCostOfThisOperationInUSD),
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
@ -107,13 +108,13 @@ export class Service extends DatabaseService<Model> {
|
||||
const usageBilling: Model = new Model();
|
||||
usageBilling.projectId = data.projectId;
|
||||
usageBilling.productType = data.productType;
|
||||
usageBilling.usageCount = data.usageCount;
|
||||
usageBilling.usageCount = new Decimal(data.usageCount);
|
||||
usageBilling.isReportedToBillingProvider = false;
|
||||
usageBilling.createdAt = OneUptimeDate.getCurrentDate();
|
||||
usageBilling.day = OneUptimeDate.getDateString(
|
||||
OneUptimeDate.getCurrentDate()
|
||||
);
|
||||
usageBilling.totalCostInUSD = totalCostOfThisOperationInUSD;
|
||||
usageBilling.totalCostInUSD = new Decimal(totalCostOfThisOperationInUSD);
|
||||
usageBilling.usageUnitName = meteredPlan.getUnitName(); // e.g. "GB"
|
||||
|
||||
await this.create({
|
||||
|
@ -12,6 +12,7 @@ import FieldType from 'CommonUI/src/Components/Types/FieldType';
|
||||
import DashboardNavigation from '../../Utils/Navigation';
|
||||
import Currency from 'Common/Types/Currency';
|
||||
import DiskSize from 'Common/Types/DiskSize';
|
||||
import Decimal from 'Common/Types/Decimal';
|
||||
|
||||
export interface ComponentProps extends PageComponentProps {}
|
||||
|
||||
@ -93,7 +94,7 @@ const Settings: FunctionComponent<ComponentProps> = (
|
||||
getElement: (item: JSONObject) => {
|
||||
return (
|
||||
<div>{`${DiskSize.convertToDecimalPlaces(
|
||||
item['usageCount'] as number
|
||||
(item['usageCount'] as Decimal).value as number
|
||||
)} ${item['usageUnitName'] as string}`}</div>
|
||||
);
|
||||
},
|
||||
@ -107,7 +108,7 @@ const Settings: FunctionComponent<ComponentProps> = (
|
||||
getElement: (item: JSONObject) => {
|
||||
return (
|
||||
<div>{`${Currency.convertToDecimalPlaces(
|
||||
item['totalCostInUSD'] as number
|
||||
(item['totalCostInUSD'] as Decimal).value as number
|
||||
)} USD`}</div>
|
||||
);
|
||||
},
|
||||
|
@ -7,6 +7,8 @@ using OpenTelemetry.Trace;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
const string endpoint = "http://localhost:4317";
|
||||
|
||||
Console.WriteLine($"Env var: {Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_HEADERS")?.ToString()}");
|
||||
|
||||
|
||||
@ -28,6 +30,15 @@ builder.Logging.AddOpenTelemetry(logging =>
|
||||
.AddConsoleExporter()
|
||||
.AddOtlpExporter(opt =>
|
||||
{
|
||||
// If endpoint was not specified, the proper one will be selected according to the protocol.
|
||||
if (!string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
opt.Endpoint = new Uri(endpoint);
|
||||
|
||||
// Set headers in OTLP exporter
|
||||
// opt.Headers = "oneuptime-service-token=0a00ebc0-7f39-11ee-ac8c-3fb43926b224";
|
||||
}
|
||||
|
||||
System.Console.WriteLine($"OTLP Exporter is using {opt.Protocol} protocol and endpoint {opt.Endpoint}");
|
||||
});
|
||||
});
|
||||
@ -41,6 +52,16 @@ builder.Services.AddOpenTelemetry()
|
||||
.AddConsoleExporter()
|
||||
.AddOtlpExporter(opt =>
|
||||
{
|
||||
// If endpoint was not specified, the proper one will be selected according to the protocol.
|
||||
if (!string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
opt.Endpoint = new Uri(endpoint);
|
||||
// Set headers in OTLP exporter
|
||||
// opt.Headers = "oneuptime-service-token=0a00ebc0-7f39-11ee-ac8c-3fb43926b224";
|
||||
|
||||
|
||||
}
|
||||
|
||||
System.Console.WriteLine($"OTLP Exporter is using {opt.Protocol} protocol and endpoint {opt.Endpoint}");
|
||||
}));
|
||||
|
||||
@ -61,6 +82,14 @@ builder.Services.AddOpenTelemetry()
|
||||
})
|
||||
.AddOtlpExporter(opt =>
|
||||
{
|
||||
// If endpoint was not specified, the proper one will be selected according to the protocol.
|
||||
if (!string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
opt.Endpoint = new Uri(endpoint);
|
||||
// Set headers in OTLP exporter
|
||||
// opt.Headers = "oneuptime-service-token=0a00ebc0-7f39-11ee-ac8c-3fb43926b224";
|
||||
}
|
||||
|
||||
System.Console.WriteLine($"OTLP Exporter is using {opt.Protocol} protocol and endpoint {opt.Endpoint}");
|
||||
|
||||
}));
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -40,3 +40,4 @@
|
||||
2.0
|
||||
2.0
|
||||
2.0
|
||||
2.0
|
||||
|
@ -68,8 +68,10 @@
|
||||
value: {{ $.Values.port.dashboard | squote }}
|
||||
- name: ADMIN_DASHBOARD_PORT
|
||||
value: {{ $.Values.port.adminDashboard | squote }}
|
||||
- name: OTEL_COLLECTOR_PORT
|
||||
value: {{ $.Values.port.otelCollector | squote }}
|
||||
- name: OTEL_COLLECTOR_GRPC_PORT
|
||||
value: {{ $.Values.port.otelCollectorGrpc | squote }}
|
||||
- name: OTEL_COLLECTOR_HTTP_PORT
|
||||
value: {{ $.Values.port.otelCollectorHttp | squote }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
|
@ -147,7 +147,8 @@ port:
|
||||
nginx: 80
|
||||
haraka: 2525
|
||||
probe: 3500
|
||||
otelCollector: 4317
|
||||
otelCollectorGrpc: 4317
|
||||
otelCollectorHttp: 4318
|
||||
|
||||
|
||||
testServer:
|
||||
|
@ -35,9 +35,11 @@ import { ProductType } from 'Model/Models/UsageBilling';
|
||||
const LogsProto: protobuf.Root = protobuf.loadSync(
|
||||
'/usr/src/app/ProtoFiles/OTel/v1/logs.proto'
|
||||
);
|
||||
|
||||
const TracesProto: protobuf.Root = protobuf.loadSync(
|
||||
'/usr/src/app/ProtoFiles/OTel/v1/traces.proto'
|
||||
);
|
||||
|
||||
const MetricsProto: protobuf.Root = protobuf.loadSync(
|
||||
'/usr/src/app/ProtoFiles/OTel/v1/metrics.proto'
|
||||
);
|
||||
@ -63,6 +65,19 @@ router.use(
|
||||
'/otel/*',
|
||||
async (req: ExpressRequest, _res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
|
||||
// check header.
|
||||
|
||||
const serviceTokenInHeader: string | undefined = req.headers[
|
||||
'x-oneuptime-service-token'
|
||||
] as string | undefined;
|
||||
|
||||
if (!serviceTokenInHeader) {
|
||||
throw new BadRequestException(
|
||||
'Missing header: x-oneuptime-service-token'
|
||||
);
|
||||
}
|
||||
|
||||
// size of req.body in bytes.
|
||||
const sizeInBytes: number = Buffer.byteLength(
|
||||
JSON.stringify(req.body)
|
||||
@ -85,17 +100,7 @@ router.use(
|
||||
throw new BadRequestException('Invalid URL: ' + req.baseUrl);
|
||||
}
|
||||
|
||||
// check header.
|
||||
|
||||
const serviceTokenInHeader: string | undefined = req.headers[
|
||||
'x-oneuptime-service-token'
|
||||
] as string | undefined;
|
||||
|
||||
if (!serviceTokenInHeader) {
|
||||
throw new BadRequestException(
|
||||
'Missing header: oneuptime-service-token'
|
||||
);
|
||||
}
|
||||
|
||||
const cachedServiceId: string | null = await GlobalCache.getString(
|
||||
'service-token',
|
||||
|
@ -16,6 +16,7 @@ import ColumnAccessControl from 'Common/Types/Database/AccessControl/ColumnAcces
|
||||
import TenantColumn from 'Common/Types/Database/TenantColumn';
|
||||
import TableMetadata from 'Common/Types/Database/TableMetadata';
|
||||
import IconProp from 'Common/Types/Icon/IconProp';
|
||||
import Decimal from 'Common/Types/Decimal';
|
||||
|
||||
export enum ProductType {
|
||||
Logs = 'Logs',
|
||||
@ -170,8 +171,9 @@ export default class UsageBilling extends AccessControlModel {
|
||||
@Column({
|
||||
nullable: false,
|
||||
type: ColumnType.Decimal,
|
||||
transformer: Decimal.getDatabaseTransformer()
|
||||
})
|
||||
public usageCount?: number = undefined;
|
||||
public usageCount?: Decimal = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
@ -216,8 +218,9 @@ export default class UsageBilling extends AccessControlModel {
|
||||
@Column({
|
||||
nullable: false,
|
||||
type: ColumnType.Decimal,
|
||||
transformer: Decimal.getDatabaseTransformer()
|
||||
})
|
||||
public totalCostInUSD?: number = undefined;
|
||||
public totalCostInUSD?: Decimal = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
|
@ -104,7 +104,8 @@ ACCOUNTS_PORT=3003
|
||||
STATUS_PAGE_PORT=3105
|
||||
DASHBOARD_PORT=3009
|
||||
ADMIN_DASHBOARD_PORT=3158
|
||||
OTEL_COLLECTOR_PORT=4317
|
||||
OTEL_COLLECTOR_GRPC_PORT=4317
|
||||
OTEL_COLLECTOR_HTTP_PORT=4318
|
||||
|
||||
|
||||
# If USE_INTERNAL_SMTP is true then you need to fill these values.
|
||||
|
@ -44,7 +44,8 @@ x-common-variables: &common-variables
|
||||
STATUS_PAGE_PORT: ${STATUS_PAGE_PORT}
|
||||
DASHBOARD_PORT: ${DASHBOARD_PORT}
|
||||
ADMIN_DASHBOARD_PORT: ${ADMIN_DASHBOARD_PORT}
|
||||
OTEL_COLLECTOR_PORT: ${OTEL_COLLECTOR_PORT}
|
||||
OTEL_COLLECTOR_GRPC_PORT: ${OTEL_COLLECTOR_GRPC_PORT}
|
||||
OTEL_COLLECTOR_HTTP_PORT: ${OTEL_COLLECTOR_HTTP_PORT}
|
||||
|
||||
x-common-ui-variables: &common-ui-variables
|
||||
<<: *common-variables
|
||||
|
Loading…
Reference in New Issue
Block a user