@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.
Files changed (133) hide show
  1. package/Models/AnalyticsModels/ExceptionInstance.ts +29 -4
  2. package/Models/AnalyticsModels/Log.ts +110 -4
  3. package/Models/AnalyticsModels/Metric.ts +16 -9
  4. package/Models/AnalyticsModels/MonitorLog.ts +4 -2
  5. package/Models/AnalyticsModels/Span.ts +79 -6
  6. package/Models/DatabaseModels/Index.ts +8 -0
  7. package/Models/DatabaseModels/LogDropFilter.ts +480 -0
  8. package/Models/DatabaseModels/LogPipeline.ts +412 -0
  9. package/Models/DatabaseModels/LogPipelineProcessor.ts +430 -0
  10. package/Models/DatabaseModels/LogScrubRule.ts +516 -0
  11. package/Server/API/TelemetryAPI.ts +261 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1773402621107-MigrationName.ts +131 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.ts +79 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.ts +41 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1773676206197-MigrationName.ts +57 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  17. package/Server/Middleware/WhatsAppAuthorization.ts +87 -0
  18. package/Server/Services/AnalyticsDatabaseService.ts +61 -0
  19. package/Server/Services/LogAggregationService.ts +238 -1
  20. package/Server/Services/LogDropFilterService.ts +10 -0
  21. package/Server/Services/LogPipelineProcessorService.ts +10 -0
  22. package/Server/Services/LogPipelineService.ts +10 -0
  23. package/Server/Services/LogScrubRuleService.ts +10 -0
  24. package/Server/Services/TelemetryAttributeService.ts +4 -6
  25. package/Server/Utils/AnalyticsDatabase/Statement.ts +15 -1
  26. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +138 -11
  27. package/Tests/Server/Services/LogAggregationService.test.ts +3 -2
  28. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +9 -0
  29. package/Types/AnalyticsDatabase/TableColumnType.ts +4 -0
  30. package/Types/Date.ts +22 -0
  31. package/Types/Log/LogDropFilterAction.ts +6 -0
  32. package/Types/Log/LogPipelineProcessorType.ts +44 -0
  33. package/Types/Log/LogScrubAction.ts +7 -0
  34. package/Types/Log/LogScrubPatternType.ts +10 -0
  35. package/Types/Permission.ts +174 -0
  36. package/UI/Components/LogsViewer/LogsViewer.tsx +152 -4
  37. package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +92 -0
  38. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +332 -117
  39. package/UI/Components/LogsViewer/components/LogSearchBar.tsx +294 -274
  40. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +513 -234
  41. package/UI/Components/LogsViewer/components/LogsFilterCard.tsx +37 -29
  42. package/UI/Components/LogsViewer/components/LogsTable.tsx +6 -1
  43. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +106 -0
  44. package/UI/Utils/LogExport.ts +160 -0
  45. package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +28 -4
  46. package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -1
  47. package/build/dist/Models/AnalyticsModels/Log.js +97 -4
  48. package/build/dist/Models/AnalyticsModels/Log.js.map +1 -1
  49. package/build/dist/Models/AnalyticsModels/Metric.js +16 -9
  50. package/build/dist/Models/AnalyticsModels/Metric.js.map +1 -1
  51. package/build/dist/Models/AnalyticsModels/MonitorLog.js +4 -2
  52. package/build/dist/Models/AnalyticsModels/MonitorLog.js.map +1 -1
  53. package/build/dist/Models/AnalyticsModels/Span.js +73 -6
  54. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  55. package/build/dist/Models/DatabaseModels/Index.js +8 -0
  56. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  57. package/build/dist/Models/DatabaseModels/LogDropFilter.js +508 -0
  58. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -0
  59. package/build/dist/Models/DatabaseModels/LogPipeline.js +438 -0
  60. package/build/dist/Models/DatabaseModels/LogPipeline.js.map +1 -0
  61. package/build/dist/Models/DatabaseModels/LogPipelineProcessor.js +452 -0
  62. package/build/dist/Models/DatabaseModels/LogPipelineProcessor.js.map +1 -0
  63. package/build/dist/Models/DatabaseModels/LogScrubRule.js +545 -0
  64. package/build/dist/Models/DatabaseModels/LogScrubRule.js.map +1 -0
  65. package/build/dist/Server/API/TelemetryAPI.js +155 -0
  66. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  67. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773402621107-MigrationName.js +52 -0
  68. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773402621107-MigrationName.js.map +1 -0
  69. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.js +34 -0
  70. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773414578773-MigrationName.js.map +1 -0
  71. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.js +22 -0
  72. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773500000000-MigrationName.js.map +1 -0
  73. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773676206197-MigrationName.js +26 -0
  74. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1773676206197-MigrationName.js.map +1 -0
  75. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  76. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  77. package/build/dist/Server/Middleware/WhatsAppAuthorization.js +58 -0
  78. package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -0
  79. package/build/dist/Server/Services/AnalyticsDatabaseService.js +30 -0
  80. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  81. package/build/dist/Server/Services/LogAggregationService.js +188 -1
  82. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  83. package/build/dist/Server/Services/LogDropFilterService.js +9 -0
  84. package/build/dist/Server/Services/LogDropFilterService.js.map +1 -0
  85. package/build/dist/Server/Services/LogPipelineProcessorService.js +9 -0
  86. package/build/dist/Server/Services/LogPipelineProcessorService.js.map +1 -0
  87. package/build/dist/Server/Services/LogPipelineService.js +9 -0
  88. package/build/dist/Server/Services/LogPipelineService.js.map +1 -0
  89. package/build/dist/Server/Services/LogScrubRuleService.js +9 -0
  90. package/build/dist/Server/Services/LogScrubRuleService.js.map +1 -0
  91. package/build/dist/Server/Services/TelemetryAttributeService.js +4 -6
  92. package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
  93. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +13 -1
  94. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  95. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +98 -2
  96. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  97. package/build/dist/Tests/Server/Services/LogAggregationService.test.js +3 -2
  98. package/build/dist/Tests/Server/Services/LogAggregationService.test.js.map +1 -1
  99. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  100. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -0
  101. package/build/dist/Types/AnalyticsDatabase/TableColumnType.js +4 -0
  102. package/build/dist/Types/AnalyticsDatabase/TableColumnType.js.map +1 -1
  103. package/build/dist/Types/Date.js +16 -0
  104. package/build/dist/Types/Date.js.map +1 -1
  105. package/build/dist/Types/Log/LogDropFilterAction.js +7 -0
  106. package/build/dist/Types/Log/LogDropFilterAction.js.map +1 -0
  107. package/build/dist/Types/Log/LogPipelineProcessorType.js +9 -0
  108. package/build/dist/Types/Log/LogPipelineProcessorType.js.map +1 -0
  109. package/build/dist/Types/Log/LogScrubAction.js +8 -0
  110. package/build/dist/Types/Log/LogScrubAction.js.map +1 -0
  111. package/build/dist/Types/Log/LogScrubPatternType.js +11 -0
  112. package/build/dist/Types/Log/LogScrubPatternType.js.map +1 -0
  113. package/build/dist/Types/Permission.js +152 -0
  114. package/build/dist/Types/Permission.js.map +1 -1
  115. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +124 -11
  116. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  117. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +36 -0
  118. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -0
  119. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +114 -4
  120. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  121. package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js +17 -5
  122. package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js.map +1 -1
  123. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +229 -122
  124. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  125. package/build/dist/UI/Components/LogsViewer/components/LogsFilterCard.js +5 -4
  126. package/build/dist/UI/Components/LogsViewer/components/LogsFilterCard.js.map +1 -1
  127. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +4 -1
  128. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  129. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +28 -0
  130. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  131. package/build/dist/UI/Utils/LogExport.js +129 -0
  132. package/build/dist/UI/Utils/LogExport.js.map +1 -0
  133. 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: Record): string {
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<Record>): string {
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<Record> = [];
129
+ const records: Array<AnalyticsRecord> = [];
130
130
 
131
131
  for (const item of data.item) {
132
- const record: Record = this.getRecord(item);
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): Record {
158
- const record: 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.LongNumber,
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: "LogItem",
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: "LogItem",
59
+ p1: AnalyticsTableName.Log,
59
60
  p2: defaultRequest.projectId.toString(),
60
61
  p3: OneUptimeDate.toClickhouseDateTime(defaultRequest.startTime),
61
62
  p4: OneUptimeDate.toClickhouseDateTime(defaultRequest.endTime),
@@ -0,0 +1,9 @@
1
+ enum AnalyticsTableName {
2
+ Log = "LogItemV2",
3
+ Metric = "MetricItemV2",
4
+ ExceptionInstance = "ExceptionItemV2",
5
+ Span = "SpanItemV2",
6
+ MonitorLog = "MonitorLogV2",
7
+ }
8
+
9
+ export default AnalyticsTableName;
@@ -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,6 @@
1
+ enum LogDropFilterAction {
2
+ Drop = "drop",
3
+ Sample = "sample",
4
+ }
5
+
6
+ export default LogDropFilterAction;
@@ -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;
@@ -0,0 +1,7 @@
1
+ enum LogScrubAction {
2
+ Mask = "mask",
3
+ Hash = "hash",
4
+ Redact = "redact",
5
+ }
6
+
7
+ export default LogScrubAction;
@@ -0,0 +1,10 @@
1
+ enum LogScrubPatternType {
2
+ Email = "email",
3
+ CreditCard = "creditCard",
4
+ SSN = "ssn",
5
+ PhoneNumber = "phoneNumber",
6
+ IPAddress = "ipAddress",
7
+ Custom = "custom",
8
+ }
9
+
10
+ export default LogScrubPatternType;
@@ -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",