Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Logs Overview] Overview component (iteration 1) (attempt 2) #195673

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
b3a1af8
Add rare logs scenario
weltenwort Aug 20, 2024
0a43169
Add empty logs_overview package
weltenwort Aug 21, 2024
d373e59
Add gaussian distribution to the unstructured logs scenario
weltenwort Sep 2, 2024
278365e
Add support for xstate5
weltenwort Sep 2, 2024
1f4bd0f
Add xstate5 console inspector
weltenwort Sep 2, 2024
76ea2a5
Add cateogorization service
weltenwort Sep 2, 2024
0528e8b
Add categories grid
weltenwort Sep 2, 2024
0b7fc2c
Enable translation linting for the package
weltenwort Sep 2, 2024
b428bd4
Improve typing of the sorting config
weltenwort Sep 2, 2024
5be73af
Improve default column widths
weltenwort Sep 2, 2024
e0af1bb
Add loading screen with cancellation
weltenwort Sep 2, 2024
c70a37a
Merge branch 'main' into logs-enhanced-embeddable-iteration-1
weltenwort Sep 3, 2024
169df23
Bump XState 5 version
weltenwort Sep 3, 2024
901bee3
Start cleaning up names and introducing the overview component
weltenwort Sep 3, 2024
1023d69
Provide a self-contained overview via logs_shared
weltenwort Sep 4, 2024
0d35529
Fix unnecessary uiSettings dependency
weltenwort Sep 4, 2024
d551da4
Fix some refactoring mistakes
weltenwort Sep 4, 2024
47153c8
Memoize time overview props
weltenwort Sep 4, 2024
dc8ea70
Update zod import
weltenwort Sep 5, 2024
3793877
Add service filters and error reporting
weltenwort Sep 5, 2024
c69a83b
Fix fetching remaining categories
weltenwort Sep 5, 2024
870d347
Add logs overview feature flag
weltenwort Sep 6, 2024
d08f104
Add logs overview in infra hosts
weltenwort Sep 6, 2024
6ecd056
Fix sampling probability of second pass
weltenwort Sep 6, 2024
b0b1fe7
Signal categories limit being reached
weltenwort Sep 6, 2024
8c09788
Respect the abort signal when categorizing
weltenwort Sep 6, 2024
b028eab
Add empty state screen
weltenwort Sep 6, 2024
6a1ed55
Merge branch 'main' of github.com:elastic/kibana into logs-enhanced-e…
weltenwort Sep 9, 2024
463355c
Merge branch 'main' of github.com:elastic/kibana into logs-enhanced-e…
weltenwort Sep 12, 2024
6aad1a1
Fix race condition when rendering apm service details
weltenwort Sep 12, 2024
7f1fb14
Improve loading content in hosts
weltenwort Sep 12, 2024
4e95f04
Update XState v5 version
weltenwort Sep 16, 2024
ea9dfb2
Merge branch 'main' of github.com:elastic/kibana into logs-enhanced-e…
weltenwort Sep 16, 2024
a6ab7e1
Clean up TODOs and comments
weltenwort Sep 16, 2024
5bbda50
Remove temporary test
weltenwort Sep 16, 2024
7843215
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Sep 16, 2024
e3f3043
Update license headers
weltenwort Sep 16, 2024
3402293
Remove unused import
weltenwort Sep 16, 2024
542d1f1
Revert term separators back to asterisks
weltenwort Sep 16, 2024
eb089a6
Add a logs_overview mock
weltenwort Sep 16, 2024
78b0d4c
Fix telemetry schema
weltenwort Sep 16, 2024
76b9771
Merge branch 'main' of github.com:elastic/kibana into logs-enhanced-e…
weltenwort Sep 16, 2024
2d414c5
Merge branch 'main' of github.com:elastic/kibana into logs-enhanced-e…
weltenwort Sep 17, 2024
14be0af
Merge branch 'main' of github.com:elastic/kibana into logs-enhanced-e…
weltenwort Sep 18, 2024
c1962c0
Add link to open all log entries in discover
weltenwort Sep 18, 2024
90282cc
Fix dataview spec passed to locator
weltenwort Sep 18, 2024
6e77e63
Merge branch 'main' of github.com:elastic/kibana into logs-enhanced-e…
weltenwort Sep 18, 2024
1a90cb8
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Sep 18, 2024
70adf04
Merge remote-tracking branch 'upstream/main' into logs-enhanced-embed…
Kerry350 Sep 23, 2024
b522494
Merge remote-tracking branch 'upstream/main' into logs-enhanced-embed…
Kerry350 Oct 2, 2024
598d9a9
package.json changes from yarn kbn bootstrap
Kerry350 Oct 3, 2024
a34ab22
Fix two types
Kerry350 Oct 3, 2024
eb3f98c
Merge branch 'main' into logs-enhanced-embeddable-iteration-1
elasticmachine Oct 3, 2024
4940642
Merge remote-tracking branch 'upstream/main' into logs-enhanced-embed…
weltenwort Oct 9, 2024
46f8e9e
Merge branch 'main' into logs-enhanced-embeddable-iteration-1
elasticmachine Oct 9, 2024
c6d26db
Use timeField parameter instead of hard-coded field name
weltenwort Oct 9, 2024
782e0b9
Fix storybook webpack config
weltenwort Oct 9, 2024
70000e3
Remove accidental character in logs tab content
weltenwort Oct 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ module.exports = {
files: [
'x-pack/plugins/observability_solution/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)',
'src/plugins/ai_assistant_management/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)',
'x-pack/packages/observability/logs_overview/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)',
],
rules: {
'@kbn/i18n/strings_should_be_translated_with_i18n': 'warn',
Expand Down
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ x-pack/packages/observability/alerting_test_data @elastic/obs-ux-management-team
x-pack/test/cases_api_integration/common/plugins/observability @elastic/response-ops
x-pack/packages/observability/get_padded_alert_time_range_util @elastic/obs-ux-management-team
x-pack/plugins/observability_solution/observability_logs_explorer @elastic/obs-ux-logs-team
x-pack/packages/observability/logs_overview @elastic/obs-ux-logs-team
x-pack/plugins/observability_solution/observability_onboarding/e2e @elastic/obs-ux-logs-team @elastic/obs-ux-onboarding-team
x-pack/plugins/observability_solution/observability_onboarding @elastic/obs-ux-logs-team @elastic/obs-ux-onboarding-team
x-pack/plugins/observability_solution/observability @elastic/obs-ux-management-team
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
"@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.cd77847.0",
"@types/react": "~18.2.0",
"@types/react-dom": "~18.2.0",
"@xstate5/react/**/xstate": "^5.18.1",
"globby/fast-glob": "^3.2.11"
},
"dependencies": {
Expand Down Expand Up @@ -687,6 +688,7 @@
"@kbn/observability-fixtures-plugin": "link:x-pack/test/cases_api_integration/common/plugins/observability",
"@kbn/observability-get-padded-alert-time-range-util": "link:x-pack/packages/observability/get_padded_alert_time_range_util",
"@kbn/observability-logs-explorer-plugin": "link:x-pack/plugins/observability_solution/observability_logs_explorer",
"@kbn/observability-logs-overview": "link:x-pack/packages/observability/logs_overview",
"@kbn/observability-onboarding-plugin": "link:x-pack/plugins/observability_solution/observability_onboarding",
"@kbn/observability-plugin": "link:x-pack/plugins/observability_solution/observability",
"@kbn/observability-shared-plugin": "link:x-pack/plugins/observability_solution/observability_shared",
Expand Down Expand Up @@ -1050,6 +1052,7 @@
"@turf/helpers": "6.0.1",
"@turf/length": "^6.0.2",
"@xstate/react": "^3.2.2",
"@xstate5/react": "npm:@xstate/react@^4.1.2",
"adm-zip": "^0.5.9",
"ai": "^2.2.33",
"ajv": "^8.12.0",
Expand Down Expand Up @@ -1283,6 +1286,7 @@
"whatwg-fetch": "^3.0.0",
"xml2js": "^0.5.0",
"xstate": "^4.38.2",
"xstate5": "npm:xstate@^5.18.1",
"xterm": "^5.1.0",
"yauzl": "^2.10.0",
"yazl": "^2.5.1",
Expand All @@ -1304,6 +1308,7 @@
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@babel/plugin-transform-class-properties": "^7.24.7",
"@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
"@babel/plugin-transform-numeric-separator": "^7.24.7",
"@babel/plugin-transform-runtime": "^7.24.7",
"@babel/preset-env": "^7.24.7",
Expand Down
12 changes: 12 additions & 0 deletions packages/kbn-apm-synthtrace-client/src/lib/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

export type ObjectEntry<T> = [keyof T, T[keyof T]];

export type Fields<TMeta extends Record<string, any> | undefined = undefined> = {
'@timestamp'?: number;
} & (TMeta extends undefined ? {} : Partial<{ meta: TMeta }>);
Expand All @@ -27,4 +29,14 @@ export class Entity<TFields extends Fields> {

return this;
}

overrides(overrides: Partial<TFields>) {
const overrideEntries = Object.entries(overrides) as Array<ObjectEntry<TFields>>;

overrideEntries.forEach(([fieldName, value]) => {
this.fields[fieldName] = value;
});

return this;
}
}
74 changes: 74 additions & 0 deletions packages/kbn-apm-synthtrace-client/src/lib/gaussian_events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { castArray } from 'lodash';
import { SynthtraceGenerator } from '../types';
import { Fields } from './entity';
import { Serializable } from './serializable';

export class GaussianEvents<TFields extends Fields = Fields> {
constructor(
private readonly from: Date,
private readonly to: Date,
private readonly mean: Date,
private readonly width: number,
private readonly totalPoints: number
) {}

*generator<TGeneratedFields extends Fields = TFields>(
map: (
timestamp: number,
index: number
) => Serializable<TGeneratedFields> | Array<Serializable<TGeneratedFields>>
): SynthtraceGenerator<TGeneratedFields> {
if (this.totalPoints <= 0) {
return;
}

const startTime = this.from.getTime();
const endTime = this.to.getTime();
const meanTime = this.mean.getTime();
const densityInterval = 1 / (this.totalPoints - 1);

for (let eventIndex = 0; eventIndex < this.totalPoints; eventIndex++) {
const quantile = eventIndex * densityInterval;

const standardScore = Math.sqrt(2) * inverseError(2 * quantile - 1);
const timestamp = Math.round(meanTime + standardScore * this.width);

if (timestamp >= startTime && timestamp <= endTime) {
yield* this.generateEvents(timestamp, eventIndex, map);
}
}
}

private *generateEvents<TGeneratedFields extends Fields = TFields>(
timestamp: number,
eventIndex: number,
map: (
timestamp: number,
index: number
) => Serializable<TGeneratedFields> | Array<Serializable<TGeneratedFields>>
): Generator<Serializable<TGeneratedFields>> {
const events = castArray(map(timestamp, eventIndex));
for (const event of events) {
yield event;
}
}
}

function inverseError(x: number): number {
const a = 0.147;
const sign = x < 0 ? -1 : 1;

const part1 = 2 / (Math.PI * a) + Math.log(1 - x * x) / 2;
const part2 = Math.log(1 - x * x) / a;

return sign * Math.sqrt(Math.sqrt(part1 * part1 - part2) - part1);
}
10 changes: 9 additions & 1 deletion packages/kbn-apm-synthtrace-client/src/lib/infra/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface HostDocument extends Fields {
'cloud.provider'?: string;
}

class Host extends Entity<HostDocument> {
export class Host extends Entity<HostDocument> {
cpu({ cpuTotalValue }: { cpuTotalValue?: number } = {}) {
return new HostMetrics({
...this.fields,
Expand Down Expand Up @@ -175,3 +175,11 @@ export function host(name: string): Host {
'cloud.provider': 'gcp',
});
}

export function minimalHost(name: string): Host {
return new Host({
'agent.id': 'synthtrace',
'host.hostname': name,
'host.name': name,
});
}
3 changes: 2 additions & 1 deletion packages/kbn-apm-synthtrace-client/src/lib/infra/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { dockerContainer, DockerContainerMetricsDocument } from './docker_container';
import { host, HostMetricsDocument } from './host';
import { host, HostMetricsDocument, minimalHost } from './host';
import { k8sContainer, K8sContainerMetricsDocument } from './k8s_container';
import { pod, PodMetricsDocument } from './pod';
import { awsRds, AWSRdsMetricsDocument } from './aws/rds';
Expand All @@ -24,6 +24,7 @@ export type InfraDocument =

export const infra = {
host,
minimalHost,
pod,
dockerContainer,
k8sContainer,
Expand Down
18 changes: 15 additions & 3 deletions packages/kbn-apm-synthtrace-client/src/lib/interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ interface IntervalOptions {
rate?: number;
}

interface StepDetails {
stepMilliseconds: number;
}

export class Interval<TFields extends Fields = Fields> {
private readonly intervalAmount: number;
private readonly intervalUnit: unitOfTime.DurationConstructor;
Expand All @@ -46,12 +50,16 @@ export class Interval<TFields extends Fields = Fields> {
this._rate = options.rate || 1;
}

private getIntervalMilliseconds(): number {
return moment.duration(this.intervalAmount, this.intervalUnit).asMilliseconds();
}

private getTimestamps() {
const from = this.options.from.getTime();
const to = this.options.to.getTime();

let time: number = from;
const diff = moment.duration(this.intervalAmount, this.intervalUnit).asMilliseconds();
const diff = this.getIntervalMilliseconds();

const timestamps: number[] = [];

Expand All @@ -68,15 +76,19 @@ export class Interval<TFields extends Fields = Fields> {
*generator<TGeneratedFields extends Fields = TFields>(
map: (
timestamp: number,
index: number
index: number,
stepDetails: StepDetails
) => Serializable<TGeneratedFields> | Array<Serializable<TGeneratedFields>>
): SynthtraceGenerator<TGeneratedFields> {
const timestamps = this.getTimestamps();
const stepDetails: StepDetails = {
stepMilliseconds: this.getIntervalMilliseconds(),
};

let index = 0;

for (const timestamp of timestamps) {
const events = castArray(map(timestamp, index));
const events = castArray(map(timestamp, index, stepDetails));
index++;
for (const event of events) {
yield event;
Expand Down
21 changes: 21 additions & 0 deletions packages/kbn-apm-synthtrace-client/src/lib/logs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export type LogDocument = Fields &
'event.duration': number;
'event.start': Date;
'event.end': Date;
labels?: Record<string, string>;
test_field: string | string[];
date: Date;
severity: string;
Expand Down Expand Up @@ -156,6 +157,26 @@ function create(logsOptions: LogsOptions = defaultLogsOptions): Log {
).dataset('synth');
}

function createMinimal({
dataset = 'synth',
namespace = 'default',
}: {
dataset?: string;
namespace?: string;
} = {}): Log {
return new Log(
{
'input.type': 'logs',
'data_stream.namespace': namespace,
'data_stream.type': 'logs',
'data_stream.dataset': dataset,
'event.dataset': dataset,
},
{ isLogsDb: false }
);
}

export const log = {
create,
createMinimal,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { PoissonEvents } from './poisson_events';
import { Serializable } from './serializable';

describe('poisson events', () => {
it('generates events within the given time range', () => {
const poissonEvents = new PoissonEvents(new Date(1000), new Date(2000), 10);

const events = Array.from(
poissonEvents.generator((timestamp) => new Serializable({ '@timestamp': timestamp }))
);

expect(events.length).toBeGreaterThanOrEqual(1);

for (const event of events) {
expect(event.fields['@timestamp']).toBeGreaterThanOrEqual(1000);
expect(event.fields['@timestamp']).toBeLessThanOrEqual(2000);
}
});

it('generates at least one event if the rate is greater than 0', () => {
const poissonEvents = new PoissonEvents(new Date(1000), new Date(2000), 1);

const events = Array.from(
poissonEvents.generator((timestamp) => new Serializable({ '@timestamp': timestamp }))
);

expect(events.length).toBeGreaterThanOrEqual(1);

for (const event of events) {
expect(event.fields['@timestamp']).toBeGreaterThanOrEqual(1000);
expect(event.fields['@timestamp']).toBeLessThanOrEqual(2000);
}
});

it('generates no event if the rate is 0', () => {
const poissonEvents = new PoissonEvents(new Date(1000), new Date(2000), 0);

const events = Array.from(
poissonEvents.generator((timestamp) => new Serializable({ '@timestamp': timestamp }))
);

expect(events.length).toBe(0);
});
});
Loading