@oneuptime/common 10.0.31 → 10.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/ExceptionInstance.ts +29 -4
- package/Models/AnalyticsModels/Log.ts +110 -4
- package/Models/AnalyticsModels/Metric.ts +16 -9
- package/Models/AnalyticsModels/MonitorLog.ts +4 -2
- package/Models/AnalyticsModels/Span.ts +79 -6
- package/Models/DatabaseModels/Index.ts +8 -0
- package/Models/DatabaseModels/LogDropFilter.ts +480 -0
- package/Models/DatabaseModels/LogPipeline.ts +412 -0
- package/Models/DatabaseModels/LogPipelineProcessor.ts +430 -0
- package/Models/DatabaseModels/LogScrubRule.ts +516 -0
- package/Server/API/TelemetryAPI.ts +261 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1773402621107-MigrationName.ts +131 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1773676206197-MigrationName.ts +57 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/WhatsAppAuthorization.ts +87 -0
- package/Server/Services/AnalyticsDatabaseService.ts +61 -0
- package/Server/Services/LogAggregationService.ts +238 -1
- package/Server/Services/LogDropFilterService.ts +10 -0
- package/Server/Services/LogPipelineProcessorService.ts +10 -0
- package/Server/Services/LogPipelineService.ts +10 -0
- package/Server/Services/LogScrubRuleService.ts +10 -0
- package/Server/Services/TelemetryAttributeService.ts +4 -6
- package/Server/Utils/AnalyticsDatabase/Statement.ts +15 -1
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +138 -11
- package/Tests/Server/Services/LogAggregationService.test.ts +3 -2
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +9 -0
- package/Types/AnalyticsDatabase/TableColumnType.ts +4 -0
- package/Types/Date.ts +22 -0
- package/Types/Log/LogDropFilterAction.ts +6 -0
- package/Types/Log/LogPipelineProcessorType.ts +44 -0
- package/Types/Log/LogScrubAction.ts +7 -0
- package/Types/Log/LogScrubPatternType.ts +10 -0
- package/Types/Permission.ts +174 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +152 -4
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +92 -0
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +332 -117
- package/UI/Components/LogsViewer/components/LogSearchBar.tsx +294 -274
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +513 -234
- package/UI/Components/LogsViewer/components/LogsFilterCard.tsx +37 -29
- package/UI/Components/LogsViewer/components/LogsTable.tsx +6 -1
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +106 -0
- package/UI/Utils/LogExport.ts +160 -0
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +28 -4
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Log.js +97 -4
- package/build/dist/Models/AnalyticsModels/Log.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Metric.js +16 -9
- package/build/dist/Models/AnalyticsModels/Metric.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MonitorLog.js +4 -2
- package/build/dist/Models/AnalyticsModels/MonitorLog.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Span.js +73 -6
- package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +8 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +508 -0
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -0
- package/build/dist/Models/DatabaseModels/LogPipeline.js +438 -0
- package/build/dist/Models/DatabaseModels/LogPipeline.js.map +1 -0
- package/build/dist/Models/DatabaseModels/LogPipelineProcessor.js +452 -0
- package/build/dist/Models/DatabaseModels/LogPipelineProcessor.js.map +1 -0
- package/build/dist/Models/DatabaseModels/LogScrubRule.js +545 -0
- package/build/dist/Models/DatabaseModels/LogScrubRule.js.map +1 -0
- package/build/dist/Server/API/TelemetryAPI.js +155 -0
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773402621107-MigrationName.js +52 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773402621107-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773676206197-MigrationName.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773676206197-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js +58 -0
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +30 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +188 -1
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/LogDropFilterService.js +9 -0
- package/build/dist/Server/Services/LogDropFilterService.js.map +1 -0
- package/build/dist/Server/Services/LogPipelineProcessorService.js +9 -0
- package/build/dist/Server/Services/LogPipelineProcessorService.js.map +1 -0
- package/build/dist/Server/Services/LogPipelineService.js +9 -0
- package/build/dist/Server/Services/LogPipelineService.js.map +1 -0
- package/build/dist/Server/Services/LogScrubRuleService.js +9 -0
- package/build/dist/Server/Services/LogScrubRuleService.js.map +1 -0
- package/build/dist/Server/Services/TelemetryAttributeService.js +4 -6
- package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +13 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +98 -2
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Tests/Server/Services/LogAggregationService.test.js +3 -2
- package/build/dist/Tests/Server/Services/LogAggregationService.test.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -0
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js +4 -0
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js.map +1 -1
- package/build/dist/Types/Date.js +16 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Log/LogDropFilterAction.js +7 -0
- package/build/dist/Types/Log/LogDropFilterAction.js.map +1 -0
- package/build/dist/Types/Log/LogPipelineProcessorType.js +9 -0
- package/build/dist/Types/Log/LogPipelineProcessorType.js.map +1 -0
- package/build/dist/Types/Log/LogScrubAction.js +8 -0
- package/build/dist/Types/Log/LogScrubAction.js.map +1 -0
- package/build/dist/Types/Log/LogScrubPatternType.js +11 -0
- package/build/dist/Types/Log/LogScrubPatternType.js.map +1 -0
- package/build/dist/Types/Permission.js +152 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +124 -11
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +36 -0
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +114 -4
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js +17 -5
- package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +229 -122
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFilterCard.js +5 -4
- package/build/dist/UI/Components/LogsViewer/components/LogsFilterCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +4 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +28 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Utils/LogExport.js +129 -0
- package/build/dist/UI/Utils/LogExport.js.map +1 -0
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ import logger from "../Logger";
|
|
|
8
8
|
import { SQL, Statement } from "./Statement";
|
|
9
9
|
import AnalyticsBaseModel from "../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
|
|
10
10
|
import CommonModel, {
|
|
11
|
-
Record,
|
|
11
|
+
Record as AnalyticsRecord,
|
|
12
12
|
RecordValue,
|
|
13
13
|
} from "../../../Models/AnalyticsModels/AnalyticsBaseModel/CommonModel";
|
|
14
14
|
import AnalyticsTableColumn, {
|
|
@@ -85,7 +85,7 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
85
85
|
return columnNames;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
public getRecordValuesStatement(record:
|
|
88
|
+
public getRecordValuesStatement(record: AnalyticsRecord): string {
|
|
89
89
|
let valueStatement: string = "";
|
|
90
90
|
|
|
91
91
|
for (const value of record) {
|
|
@@ -106,7 +106,7 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
106
106
|
return valueStatement;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
public getValuesStatement(records: Array<
|
|
109
|
+
public getValuesStatement(records: Array<AnalyticsRecord>): string {
|
|
110
110
|
let statement: string = "";
|
|
111
111
|
for (const record of records) {
|
|
112
112
|
statement += `(${this.getRecordValuesStatement(record)}), `;
|
|
@@ -126,10 +126,10 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
126
126
|
this.model.getTableColumns(),
|
|
127
127
|
);
|
|
128
128
|
|
|
129
|
-
const records: Array<
|
|
129
|
+
const records: Array<AnalyticsRecord> = [];
|
|
130
130
|
|
|
131
131
|
for (const item of data.item) {
|
|
132
|
-
const record:
|
|
132
|
+
const record: AnalyticsRecord = this.getRecord(item);
|
|
133
133
|
records.push(record);
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -154,8 +154,8 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
154
154
|
return statement;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
private getRecord(item: CommonModel):
|
|
158
|
-
const record:
|
|
157
|
+
private getRecord(item: CommonModel): AnalyticsRecord {
|
|
158
|
+
const record: AnalyticsRecord = [];
|
|
159
159
|
|
|
160
160
|
for (const column of item.getTableColumns()) {
|
|
161
161
|
const value: RecordValue | undefined = this.sanitizeValue(
|
|
@@ -251,6 +251,34 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
251
251
|
value = `CAST(${this.escapeStringLiteral(value.toString())} AS Int128)`;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
if (column.type === TableColumnType.BigNumber) {
|
|
255
|
+
if (typeof value === "string") {
|
|
256
|
+
value = parseInt(value);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (column.type === TableColumnType.ArrayBigNumber) {
|
|
261
|
+
value = `[${(value as Array<number>)
|
|
262
|
+
.map((v: number) => {
|
|
263
|
+
if (v && typeof v !== "number") {
|
|
264
|
+
v = parseFloat(v);
|
|
265
|
+
return isNaN(v) ? "NULL" : v;
|
|
266
|
+
}
|
|
267
|
+
return v;
|
|
268
|
+
})
|
|
269
|
+
.join(", ")}]`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (column.type === TableColumnType.MapStringString) {
|
|
273
|
+
const mapObj: Record<string, string> = value as Record<string, string>;
|
|
274
|
+
const entries: Array<string> = Object.entries(mapObj).map(
|
|
275
|
+
([k, v]: [string, string]) => {
|
|
276
|
+
return `${this.escapeStringLiteral(k)}, ${this.escapeStringLiteral(v)}`;
|
|
277
|
+
},
|
|
278
|
+
);
|
|
279
|
+
value = `map(${entries.join(", ")})`;
|
|
280
|
+
}
|
|
281
|
+
|
|
254
282
|
return value;
|
|
255
283
|
}
|
|
256
284
|
|
|
@@ -387,6 +415,28 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
387
415
|
} else {
|
|
388
416
|
whereStatement.append(SQL`AND ${key} IS NULL`);
|
|
389
417
|
}
|
|
418
|
+
} else if (
|
|
419
|
+
tableColumn.type === TableColumnType.MapStringString &&
|
|
420
|
+
typeof value === "object"
|
|
421
|
+
) {
|
|
422
|
+
const mapValue: Record<string, string> = value as Record<
|
|
423
|
+
string,
|
|
424
|
+
string
|
|
425
|
+
>;
|
|
426
|
+
for (const mapKey in mapValue) {
|
|
427
|
+
if (mapValue[mapKey] === undefined) {
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
whereStatement.append(
|
|
431
|
+
SQL`AND ${key}[${{
|
|
432
|
+
value: mapKey,
|
|
433
|
+
type: TableColumnType.Text,
|
|
434
|
+
}}] = ${{
|
|
435
|
+
value: mapValue[mapKey] as string,
|
|
436
|
+
type: TableColumnType.Text,
|
|
437
|
+
}}`,
|
|
438
|
+
);
|
|
439
|
+
}
|
|
390
440
|
} else if (
|
|
391
441
|
(tableColumn.type === TableColumnType.JSON ||
|
|
392
442
|
tableColumn.type === TableColumnType.JSONArray) &&
|
|
@@ -453,6 +503,10 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
453
503
|
|
|
454
504
|
let first: boolean = true;
|
|
455
505
|
for (const key in groupBy) {
|
|
506
|
+
if (!this.model.getTableColumn(key)) {
|
|
507
|
+
throw new BadDataException(`Unknown column: ${key}`);
|
|
508
|
+
}
|
|
509
|
+
|
|
456
510
|
if (first) {
|
|
457
511
|
first = false;
|
|
458
512
|
} else {
|
|
@@ -468,6 +522,10 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
468
522
|
const sortStatement: Statement = new Statement();
|
|
469
523
|
|
|
470
524
|
for (const key in sort) {
|
|
525
|
+
if (!this.model.getTableColumn(key)) {
|
|
526
|
+
throw new BadDataException(`Unknown column: ${key}`);
|
|
527
|
+
}
|
|
528
|
+
|
|
471
529
|
const value: SortOrder = sort[key]!;
|
|
472
530
|
sortStatement.append(SQL`${key} `).append(
|
|
473
531
|
{
|
|
@@ -491,6 +549,10 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
491
549
|
for (const key in select) {
|
|
492
550
|
const value: any = select[key];
|
|
493
551
|
if (value) {
|
|
552
|
+
if (!this.model.getTableColumn(key)) {
|
|
553
|
+
throw new BadDataException(`Unknown column: ${key}`);
|
|
554
|
+
}
|
|
555
|
+
|
|
494
556
|
columns.push(key);
|
|
495
557
|
if (first) {
|
|
496
558
|
first = false;
|
|
@@ -640,6 +702,13 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
640
702
|
);
|
|
641
703
|
}
|
|
642
704
|
|
|
705
|
+
// Append projections after indexes
|
|
706
|
+
if (this.model.projections && this.model.projections.length > 0) {
|
|
707
|
+
for (const projection of this.model.projections) {
|
|
708
|
+
columns.append(`, PROJECTION ${projection.name} (${projection.query})`);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
643
712
|
return columns;
|
|
644
713
|
}
|
|
645
714
|
|
|
@@ -649,13 +718,16 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
649
718
|
return {
|
|
650
719
|
String: TableColumnType.Text,
|
|
651
720
|
Int32: TableColumnType.Number,
|
|
652
|
-
Int64: TableColumnType.
|
|
721
|
+
Int64: TableColumnType.BigNumber,
|
|
653
722
|
Int128: TableColumnType.LongNumber,
|
|
654
723
|
Float32: TableColumnType.Decimal,
|
|
655
724
|
Float64: TableColumnType.Decimal,
|
|
656
725
|
DateTime: TableColumnType.Date,
|
|
726
|
+
"DateTime64(9)": TableColumnType.DateTime64,
|
|
657
727
|
"Array(String)": TableColumnType.ArrayText,
|
|
658
728
|
"Array(Int32)": TableColumnType.ArrayNumber,
|
|
729
|
+
"Array(Int64)": TableColumnType.ArrayBigNumber,
|
|
730
|
+
"Map(String, String)": TableColumnType.MapStringString,
|
|
659
731
|
JSON: TableColumnType.JSON, //JSONArray is also JSON
|
|
660
732
|
Bool: TableColumnType.Boolean,
|
|
661
733
|
}[clickhouseType];
|
|
@@ -671,11 +743,15 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
671
743
|
[TableColumnType.IP]: SQL`String`,
|
|
672
744
|
[TableColumnType.Port]: SQL`String`,
|
|
673
745
|
[TableColumnType.Date]: SQL`DateTime`,
|
|
746
|
+
[TableColumnType.DateTime64]: SQL`DateTime64(9)`,
|
|
674
747
|
[TableColumnType.JSON]: SQL`String`, // we use JSON as a string because ClickHouse has really good JSON support for string types
|
|
675
748
|
[TableColumnType.JSONArray]: SQL`String`, // we use JSON as a string because ClickHouse has really good JSON support for string types
|
|
676
749
|
[TableColumnType.ArrayNumber]: SQL`Array(Int32)`,
|
|
750
|
+
[TableColumnType.ArrayBigNumber]: SQL`Array(Int64)`,
|
|
677
751
|
[TableColumnType.ArrayText]: SQL`Array(String)`,
|
|
678
752
|
[TableColumnType.LongNumber]: SQL`Int128`,
|
|
753
|
+
[TableColumnType.BigNumber]: SQL`Int64`,
|
|
754
|
+
[TableColumnType.MapStringString]: SQL`Map(String, String)`,
|
|
679
755
|
}[type];
|
|
680
756
|
|
|
681
757
|
if (!statement) {
|
|
@@ -700,12 +776,32 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
700
776
|
}
|
|
701
777
|
|
|
702
778
|
public toAddColumnStatement(column: AnalyticsTableColumn): Statement {
|
|
779
|
+
// Build column definition without skip index (indexes must be added separately via ADD INDEX)
|
|
780
|
+
const columnDef: Statement = new Statement();
|
|
781
|
+
|
|
782
|
+
columnDef
|
|
783
|
+
.append(column.key)
|
|
784
|
+
.append(SQL` `)
|
|
785
|
+
.append(
|
|
786
|
+
column.required
|
|
787
|
+
? this.toColumnType(column.type)
|
|
788
|
+
: SQL`Nullable(`
|
|
789
|
+
.append(this.toColumnType(column.type))
|
|
790
|
+
.append(SQL`)`),
|
|
791
|
+
);
|
|
792
|
+
|
|
793
|
+
if (column.codec) {
|
|
794
|
+
const codecStr: string =
|
|
795
|
+
column.codec.level !== undefined
|
|
796
|
+
? `${column.codec.codec}(${column.codec.level})`
|
|
797
|
+
: column.codec.codec;
|
|
798
|
+
columnDef.append(` CODEC(${codecStr})`);
|
|
799
|
+
}
|
|
800
|
+
|
|
703
801
|
const statement: Statement = SQL`
|
|
704
802
|
ALTER TABLE ${this.database.getDatasourceOptions().database!}.${
|
|
705
803
|
this.model.tableName
|
|
706
|
-
} ADD COLUMN IF NOT EXISTS `.append(
|
|
707
|
-
this.toColumnsCreateStatement([column]),
|
|
708
|
-
);
|
|
804
|
+
} ADD COLUMN IF NOT EXISTS `.append(columnDef);
|
|
709
805
|
|
|
710
806
|
logger.debug(`${this.model.tableName} Add Column Statement`);
|
|
711
807
|
logger.debug(statement);
|
|
@@ -713,6 +809,37 @@ export default class StatementGenerator<TBaseModel extends AnalyticsBaseModel> {
|
|
|
713
809
|
return statement;
|
|
714
810
|
}
|
|
715
811
|
|
|
812
|
+
public toAddSkipIndexStatement(
|
|
813
|
+
column: AnalyticsTableColumn,
|
|
814
|
+
): Statement | null {
|
|
815
|
+
if (!column.skipIndex) {
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
const idx: AnalyticsTableColumn["skipIndex"] = column.skipIndex;
|
|
820
|
+
const paramsStr: string =
|
|
821
|
+
idx.params && idx.params.length > 0 ? `(${idx.params.join(", ")})` : "";
|
|
822
|
+
|
|
823
|
+
const needsAssumeNotNull: boolean =
|
|
824
|
+
!column.required &&
|
|
825
|
+
(idx.type === SkipIndexType.TokenBF ||
|
|
826
|
+
idx.type === SkipIndexType.NgramBF);
|
|
827
|
+
const columnExpr: string = needsAssumeNotNull
|
|
828
|
+
? `assumeNotNull(${column.key})`
|
|
829
|
+
: column.key;
|
|
830
|
+
|
|
831
|
+
const databaseName: string = this.database.getDatasourceOptions().database!;
|
|
832
|
+
const statement: Statement = new Statement();
|
|
833
|
+
statement.append(
|
|
834
|
+
`ALTER TABLE ${databaseName}.${this.model.tableName} ADD INDEX IF NOT EXISTS ${idx.name} ${columnExpr} TYPE ${idx.type}${paramsStr} GRANULARITY ${idx.granularity}`,
|
|
835
|
+
);
|
|
836
|
+
|
|
837
|
+
logger.debug(`${this.model.tableName} Add Skip Index Statement`);
|
|
838
|
+
logger.debug(statement);
|
|
839
|
+
|
|
840
|
+
return statement;
|
|
841
|
+
}
|
|
842
|
+
|
|
716
843
|
public toDropColumnStatement(columnName: string): string {
|
|
717
844
|
const statement: string = `ALTER TABLE ${this.database.getDatasourceOptions()
|
|
718
845
|
.database!}.${this.model.tableName} DROP COLUMN IF EXISTS ${columnName}`;
|
|
@@ -2,6 +2,7 @@ import LogAggregationService, {
|
|
|
2
2
|
FacetRequest,
|
|
3
3
|
} from "../../../Server/Services/LogAggregationService";
|
|
4
4
|
import { Statement } from "../../../Server/Utils/AnalyticsDatabase/Statement";
|
|
5
|
+
import AnalyticsTableName from "../../../Types/AnalyticsDatabase/AnalyticsTableName";
|
|
5
6
|
import ObjectID from "../../../Types/ObjectID";
|
|
6
7
|
import OneUptimeDate from "../../../Types/Date";
|
|
7
8
|
import { describe, expect, test } from "@jest/globals";
|
|
@@ -35,7 +36,7 @@ describe("LogAggregationService", () => {
|
|
|
35
36
|
|
|
36
37
|
expect(statement.query_params).toStrictEqual({
|
|
37
38
|
p0: "severityText",
|
|
38
|
-
p1:
|
|
39
|
+
p1: AnalyticsTableName.Log,
|
|
39
40
|
p2: defaultRequest.projectId.toString(),
|
|
40
41
|
p3: OneUptimeDate.toClickhouseDateTime(defaultRequest.startTime),
|
|
41
42
|
p4: OneUptimeDate.toClickhouseDateTime(defaultRequest.endTime),
|
|
@@ -55,7 +56,7 @@ describe("LogAggregationService", () => {
|
|
|
55
56
|
|
|
56
57
|
expect(statement.query_params).toStrictEqual({
|
|
57
58
|
p0: facetKey,
|
|
58
|
-
p1:
|
|
59
|
+
p1: AnalyticsTableName.Log,
|
|
59
60
|
p2: defaultRequest.projectId.toString(),
|
|
60
61
|
p3: OneUptimeDate.toClickhouseDateTime(defaultRequest.startTime),
|
|
61
62
|
p4: OneUptimeDate.toClickhouseDateTime(defaultRequest.endTime),
|
|
@@ -10,8 +10,12 @@ enum ColumnType {
|
|
|
10
10
|
ArrayNumber = "Array of Numbers",
|
|
11
11
|
ArrayText = "Array of Text",
|
|
12
12
|
LongNumber = "Long Number",
|
|
13
|
+
BigNumber = "Big Number",
|
|
14
|
+
DateTime64 = "DateTime64",
|
|
13
15
|
IP = "IP",
|
|
14
16
|
Port = "Port",
|
|
17
|
+
MapStringString = "Map(String, String)",
|
|
18
|
+
ArrayBigNumber = "Array of Big Numbers",
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
export default ColumnType;
|
package/Types/Date.ts
CHANGED
|
@@ -1524,4 +1524,26 @@ export default class OneUptimeDate {
|
|
|
1524
1524
|
const parsedDate: Date = this.fromString(date);
|
|
1525
1525
|
return moment(parsedDate).utc().format("YYYY-MM-DD HH:mm:ss");
|
|
1526
1526
|
}
|
|
1527
|
+
|
|
1528
|
+
public static toClickhouseDateTime64(
|
|
1529
|
+
date: Date | string,
|
|
1530
|
+
nanoTimestamp?: number,
|
|
1531
|
+
): string {
|
|
1532
|
+
const parsedDate: Date = this.fromString(date);
|
|
1533
|
+
const base: string = moment(parsedDate).utc().format("YYYY-MM-DD HH:mm:ss");
|
|
1534
|
+
|
|
1535
|
+
let nanoFraction: string;
|
|
1536
|
+
|
|
1537
|
+
if (nanoTimestamp !== undefined && nanoTimestamp > 0) {
|
|
1538
|
+
// Extract sub-second nanoseconds from the unix nano timestamp
|
|
1539
|
+
const subSecondNanos: number = nanoTimestamp % 1_000_000_000;
|
|
1540
|
+
nanoFraction = subSecondNanos.toString().padStart(9, "0");
|
|
1541
|
+
} else {
|
|
1542
|
+
// Fall back to milliseconds from the Date object
|
|
1543
|
+
const ms: number = parsedDate.getMilliseconds();
|
|
1544
|
+
nanoFraction = (ms * 1_000_000).toString().padStart(9, "0");
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
return `${base}.${nanoFraction}`;
|
|
1548
|
+
}
|
|
1527
1549
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
enum LogPipelineProcessorType {
|
|
2
|
+
GrokParser = "GrokParser",
|
|
3
|
+
AttributeRemapper = "AttributeRemapper",
|
|
4
|
+
SeverityRemapper = "SeverityRemapper",
|
|
5
|
+
CategoryProcessor = "CategoryProcessor",
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface GrokParserConfig {
|
|
9
|
+
source: string; // field to parse, e.g. "body"
|
|
10
|
+
pattern: string; // grok pattern
|
|
11
|
+
targetPrefix?: string; // prefix for extracted attributes
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface AttributeRemapperConfig {
|
|
15
|
+
sourceKey: string; // source attribute key
|
|
16
|
+
targetKey: string; // target attribute key
|
|
17
|
+
preserveSource?: boolean; // keep original key (default false)
|
|
18
|
+
overrideOnConflict?: boolean; // overwrite if target exists (default true)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SeverityRemapperConfig {
|
|
22
|
+
sourceKey: string; // attribute key containing severity info
|
|
23
|
+
mappings: Array<{
|
|
24
|
+
matchValue: string; // value to match (case-insensitive)
|
|
25
|
+
severityText: string; // mapped severity text
|
|
26
|
+
severityNumber: number; // mapped severity number
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CategoryProcessorConfig {
|
|
31
|
+
targetKey: string; // attribute key to store the category
|
|
32
|
+
categories: Array<{
|
|
33
|
+
name: string; // category name/value
|
|
34
|
+
filterQuery: string; // condition to match
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type LogPipelineProcessorConfig =
|
|
39
|
+
| GrokParserConfig
|
|
40
|
+
| AttributeRemapperConfig
|
|
41
|
+
| SeverityRemapperConfig
|
|
42
|
+
| CategoryProcessorConfig;
|
|
43
|
+
|
|
44
|
+
export default LogPipelineProcessorType;
|
package/Types/Permission.ts
CHANGED
|
@@ -82,6 +82,30 @@ enum Permission {
|
|
|
82
82
|
EditTelemetryServiceLog = "EditTelemetryServiceLog",
|
|
83
83
|
ReadTelemetryServiceLog = "ReadTelemetryServiceLog",
|
|
84
84
|
|
|
85
|
+
// Log Pipelines
|
|
86
|
+
CreateProjectLogPipeline = "CreateProjectLogPipeline",
|
|
87
|
+
DeleteProjectLogPipeline = "DeleteProjectLogPipeline",
|
|
88
|
+
EditProjectLogPipeline = "EditProjectLogPipeline",
|
|
89
|
+
ReadProjectLogPipeline = "ReadProjectLogPipeline",
|
|
90
|
+
|
|
91
|
+
// Log Pipeline Processors
|
|
92
|
+
CreateProjectLogPipelineProcessor = "CreateProjectLogPipelineProcessor",
|
|
93
|
+
DeleteProjectLogPipelineProcessor = "DeleteProjectLogPipelineProcessor",
|
|
94
|
+
EditProjectLogPipelineProcessor = "EditProjectLogPipelineProcessor",
|
|
95
|
+
ReadProjectLogPipelineProcessor = "ReadProjectLogPipelineProcessor",
|
|
96
|
+
|
|
97
|
+
// Log Drop Filters
|
|
98
|
+
CreateProjectLogDropFilter = "CreateProjectLogDropFilter",
|
|
99
|
+
DeleteProjectLogDropFilter = "DeleteProjectLogDropFilter",
|
|
100
|
+
EditProjectLogDropFilter = "EditProjectLogDropFilter",
|
|
101
|
+
ReadProjectLogDropFilter = "ReadProjectLogDropFilter",
|
|
102
|
+
|
|
103
|
+
// Log Scrub Rules
|
|
104
|
+
CreateProjectLogScrubRule = "CreateProjectLogScrubRule",
|
|
105
|
+
DeleteProjectLogScrubRule = "DeleteProjectLogScrubRule",
|
|
106
|
+
EditProjectLogScrubRule = "EditProjectLogScrubRule",
|
|
107
|
+
ReadProjectLogScrubRule = "ReadProjectLogScrubRule",
|
|
108
|
+
|
|
85
109
|
// Exceptions
|
|
86
110
|
CreateTelemetryException = "CreateTelemetryException",
|
|
87
111
|
DeleteTelemetryException = "DeleteTelemetryException",
|
|
@@ -3981,6 +4005,156 @@ export class PermissionHelper {
|
|
|
3981
4005
|
group: PermissionGroup.Telemetry,
|
|
3982
4006
|
},
|
|
3983
4007
|
|
|
4008
|
+
// Log Pipeline Permissions
|
|
4009
|
+
{
|
|
4010
|
+
permission: Permission.CreateProjectLogPipeline,
|
|
4011
|
+
title: "Create Log Pipeline",
|
|
4012
|
+
description:
|
|
4013
|
+
"This permission can create Log Pipelines in this project.",
|
|
4014
|
+
isAssignableToTenant: true,
|
|
4015
|
+
isAccessControlPermission: false,
|
|
4016
|
+
group: PermissionGroup.Telemetry,
|
|
4017
|
+
},
|
|
4018
|
+
{
|
|
4019
|
+
permission: Permission.DeleteProjectLogPipeline,
|
|
4020
|
+
title: "Delete Log Pipeline",
|
|
4021
|
+
description:
|
|
4022
|
+
"This permission can delete Log Pipelines of this project.",
|
|
4023
|
+
isAssignableToTenant: true,
|
|
4024
|
+
isAccessControlPermission: false,
|
|
4025
|
+
group: PermissionGroup.Telemetry,
|
|
4026
|
+
},
|
|
4027
|
+
{
|
|
4028
|
+
permission: Permission.EditProjectLogPipeline,
|
|
4029
|
+
title: "Edit Log Pipeline",
|
|
4030
|
+
description: "This permission can edit Log Pipelines of this project.",
|
|
4031
|
+
isAssignableToTenant: true,
|
|
4032
|
+
isAccessControlPermission: false,
|
|
4033
|
+
group: PermissionGroup.Telemetry,
|
|
4034
|
+
},
|
|
4035
|
+
{
|
|
4036
|
+
permission: Permission.ReadProjectLogPipeline,
|
|
4037
|
+
title: "Read Log Pipeline",
|
|
4038
|
+
description: "This permission can read Log Pipelines of this project.",
|
|
4039
|
+
isAssignableToTenant: true,
|
|
4040
|
+
isAccessControlPermission: false,
|
|
4041
|
+
group: PermissionGroup.Telemetry,
|
|
4042
|
+
},
|
|
4043
|
+
|
|
4044
|
+
// Log Pipeline Processor Permissions
|
|
4045
|
+
{
|
|
4046
|
+
permission: Permission.CreateProjectLogPipelineProcessor,
|
|
4047
|
+
title: "Create Log Pipeline Processor",
|
|
4048
|
+
description:
|
|
4049
|
+
"This permission can create Log Pipeline Processors in this project.",
|
|
4050
|
+
isAssignableToTenant: true,
|
|
4051
|
+
isAccessControlPermission: false,
|
|
4052
|
+
group: PermissionGroup.Telemetry,
|
|
4053
|
+
},
|
|
4054
|
+
{
|
|
4055
|
+
permission: Permission.DeleteProjectLogPipelineProcessor,
|
|
4056
|
+
title: "Delete Log Pipeline Processor",
|
|
4057
|
+
description:
|
|
4058
|
+
"This permission can delete Log Pipeline Processors of this project.",
|
|
4059
|
+
isAssignableToTenant: true,
|
|
4060
|
+
isAccessControlPermission: false,
|
|
4061
|
+
group: PermissionGroup.Telemetry,
|
|
4062
|
+
},
|
|
4063
|
+
{
|
|
4064
|
+
permission: Permission.EditProjectLogPipelineProcessor,
|
|
4065
|
+
title: "Edit Log Pipeline Processor",
|
|
4066
|
+
description:
|
|
4067
|
+
"This permission can edit Log Pipeline Processors of this project.",
|
|
4068
|
+
isAssignableToTenant: true,
|
|
4069
|
+
isAccessControlPermission: false,
|
|
4070
|
+
group: PermissionGroup.Telemetry,
|
|
4071
|
+
},
|
|
4072
|
+
{
|
|
4073
|
+
permission: Permission.ReadProjectLogPipelineProcessor,
|
|
4074
|
+
title: "Read Log Pipeline Processor",
|
|
4075
|
+
description:
|
|
4076
|
+
"This permission can read Log Pipeline Processors of this project.",
|
|
4077
|
+
isAssignableToTenant: true,
|
|
4078
|
+
isAccessControlPermission: false,
|
|
4079
|
+
group: PermissionGroup.Telemetry,
|
|
4080
|
+
},
|
|
4081
|
+
|
|
4082
|
+
// Log Drop Filter Permissions
|
|
4083
|
+
{
|
|
4084
|
+
permission: Permission.CreateProjectLogDropFilter,
|
|
4085
|
+
title: "Create Log Drop Filter",
|
|
4086
|
+
description:
|
|
4087
|
+
"This permission can create Log Drop Filters in this project.",
|
|
4088
|
+
isAssignableToTenant: true,
|
|
4089
|
+
isAccessControlPermission: false,
|
|
4090
|
+
group: PermissionGroup.Telemetry,
|
|
4091
|
+
},
|
|
4092
|
+
{
|
|
4093
|
+
permission: Permission.DeleteProjectLogDropFilter,
|
|
4094
|
+
title: "Delete Log Drop Filter",
|
|
4095
|
+
description:
|
|
4096
|
+
"This permission can delete Log Drop Filters of this project.",
|
|
4097
|
+
isAssignableToTenant: true,
|
|
4098
|
+
isAccessControlPermission: false,
|
|
4099
|
+
group: PermissionGroup.Telemetry,
|
|
4100
|
+
},
|
|
4101
|
+
{
|
|
4102
|
+
permission: Permission.EditProjectLogDropFilter,
|
|
4103
|
+
title: "Edit Log Drop Filter",
|
|
4104
|
+
description:
|
|
4105
|
+
"This permission can edit Log Drop Filters of this project.",
|
|
4106
|
+
isAssignableToTenant: true,
|
|
4107
|
+
isAccessControlPermission: false,
|
|
4108
|
+
group: PermissionGroup.Telemetry,
|
|
4109
|
+
},
|
|
4110
|
+
{
|
|
4111
|
+
permission: Permission.ReadProjectLogDropFilter,
|
|
4112
|
+
title: "Read Log Drop Filter",
|
|
4113
|
+
description:
|
|
4114
|
+
"This permission can read Log Drop Filters of this project.",
|
|
4115
|
+
isAssignableToTenant: true,
|
|
4116
|
+
isAccessControlPermission: false,
|
|
4117
|
+
group: PermissionGroup.Telemetry,
|
|
4118
|
+
},
|
|
4119
|
+
|
|
4120
|
+
// Log Scrub Rule Permissions
|
|
4121
|
+
{
|
|
4122
|
+
permission: Permission.CreateProjectLogScrubRule,
|
|
4123
|
+
title: "Create Log Scrub Rule",
|
|
4124
|
+
description:
|
|
4125
|
+
"This permission can create Log Scrub Rules in this project.",
|
|
4126
|
+
isAssignableToTenant: true,
|
|
4127
|
+
isAccessControlPermission: false,
|
|
4128
|
+
group: PermissionGroup.Telemetry,
|
|
4129
|
+
},
|
|
4130
|
+
{
|
|
4131
|
+
permission: Permission.DeleteProjectLogScrubRule,
|
|
4132
|
+
title: "Delete Log Scrub Rule",
|
|
4133
|
+
description:
|
|
4134
|
+
"This permission can delete Log Scrub Rules of this project.",
|
|
4135
|
+
isAssignableToTenant: true,
|
|
4136
|
+
isAccessControlPermission: false,
|
|
4137
|
+
group: PermissionGroup.Telemetry,
|
|
4138
|
+
},
|
|
4139
|
+
{
|
|
4140
|
+
permission: Permission.EditProjectLogScrubRule,
|
|
4141
|
+
title: "Edit Log Scrub Rule",
|
|
4142
|
+
description:
|
|
4143
|
+
"This permission can edit Log Scrub Rules of this project.",
|
|
4144
|
+
isAssignableToTenant: true,
|
|
4145
|
+
isAccessControlPermission: false,
|
|
4146
|
+
group: PermissionGroup.Telemetry,
|
|
4147
|
+
},
|
|
4148
|
+
{
|
|
4149
|
+
permission: Permission.ReadProjectLogScrubRule,
|
|
4150
|
+
title: "Read Log Scrub Rule",
|
|
4151
|
+
description:
|
|
4152
|
+
"This permission can read Log Scrub Rules of this project.",
|
|
4153
|
+
isAssignableToTenant: true,
|
|
4154
|
+
isAccessControlPermission: false,
|
|
4155
|
+
group: PermissionGroup.Telemetry,
|
|
4156
|
+
},
|
|
4157
|
+
|
|
3984
4158
|
{
|
|
3985
4159
|
permission: Permission.CreateTelemetryException,
|
|
3986
4160
|
title: "Create Telemetry Service Exception",
|