@openchoreo/backstage-plugin-openchoreo-observability 1.1.0
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/CHANGELOG.md +5 -0
- package/README.md +22 -0
- package/dist/api/FinOpsAgentApi.esm.js +43 -0
- package/dist/api/FinOpsAgentApi.esm.js.map +1 -0
- package/dist/api/ObservabilityApi.esm.js +568 -0
- package/dist/api/ObservabilityApi.esm.js.map +1 -0
- package/dist/api/ObserverUrlCache.esm.js +59 -0
- package/dist/api/ObserverUrlCache.esm.js.map +1 -0
- package/dist/api/RCAAgentApi.esm.js +104 -0
- package/dist/api/RCAAgentApi.esm.js.map +1 -0
- package/dist/components/Alerts/AlertRow.esm.js +203 -0
- package/dist/components/Alerts/AlertRow.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsActions.esm.js +77 -0
- package/dist/components/Alerts/AlertsActions.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsFilter.esm.js +95 -0
- package/dist/components/Alerts/AlertsFilter.esm.js.map +1 -0
- package/dist/components/Alerts/AlertsTable.esm.js +63 -0
- package/dist/components/Alerts/AlertsTable.esm.js.map +1 -0
- package/dist/components/Alerts/ObservabilityAlertsPage.esm.js +251 -0
- package/dist/components/Alerts/ObservabilityAlertsPage.esm.js.map +1 -0
- package/dist/components/Alerts/types.esm.js +4 -0
- package/dist/components/Alerts/types.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisPage.esm.js +141 -0
- package/dist/components/CostAnalysis/CostAnalysisPage.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisReport.esm.js +128 -0
- package/dist/components/CostAnalysis/CostAnalysisReport.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js +517 -0
- package/dist/components/CostAnalysis/CostAnalysisReportView.esm.js.map +1 -0
- package/dist/components/CostAnalysis/CostAnalysisTable.esm.js +149 -0
- package/dist/components/CostAnalysis/CostAnalysisTable.esm.js.map +1 -0
- package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js +112 -0
- package/dist/components/CostAnalysis/FinOpsApplyButton.esm.js.map +1 -0
- package/dist/components/CostAnalysis/index.esm.js +2 -0
- package/dist/components/CostAnalysis/index.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentRow.esm.js +258 -0
- package/dist/components/Incidents/IncidentRow.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsActions.esm.js +77 -0
- package/dist/components/Incidents/IncidentsActions.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsFilter.esm.js +144 -0
- package/dist/components/Incidents/IncidentsFilter.esm.js.map +1 -0
- package/dist/components/Incidents/IncidentsTable.esm.js +68 -0
- package/dist/components/Incidents/IncidentsTable.esm.js.map +1 -0
- package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js +283 -0
- package/dist/components/Incidents/ObservabilityProjectIncidentsPage.esm.js.map +1 -0
- package/dist/components/Incidents/types.esm.js +8 -0
- package/dist/components/Incidents/types.esm.js.map +1 -0
- package/dist/components/Metrics/ChartTooltip.esm.js +53 -0
- package/dist/components/Metrics/ChartTooltip.esm.js.map +1 -0
- package/dist/components/Metrics/HTTPMetricsSection.esm.js +109 -0
- package/dist/components/Metrics/HTTPMetricsSection.esm.js.map +1 -0
- package/dist/components/Metrics/MetricGraphByComponent.esm.js +99 -0
- package/dist/components/Metrics/MetricGraphByComponent.esm.js.map +1 -0
- package/dist/components/Metrics/MetricsActions.esm.js +30 -0
- package/dist/components/Metrics/MetricsActions.esm.js.map +1 -0
- package/dist/components/Metrics/MetricsFilters.esm.js +49 -0
- package/dist/components/Metrics/MetricsFilters.esm.js.map +1 -0
- package/dist/components/Metrics/ObservabilityMetricsPage.esm.js +196 -0
- package/dist/components/Metrics/ObservabilityMetricsPage.esm.js.map +1 -0
- package/dist/components/Metrics/styles.esm.js +55 -0
- package/dist/components/Metrics/styles.esm.js.map +1 -0
- package/dist/components/Metrics/utils.esm.js +221 -0
- package/dist/components/Metrics/utils.esm.js.map +1 -0
- package/dist/components/RCA/RCAActions.esm.js +42 -0
- package/dist/components/RCA/RCAActions.esm.js.map +1 -0
- package/dist/components/RCA/RCAFilters.esm.js +100 -0
- package/dist/components/RCA/RCAFilters.esm.js.map +1 -0
- package/dist/components/RCA/RCAPage.esm.js +137 -0
- package/dist/components/RCA/RCAPage.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js +9 -0
- package/dist/components/RCA/RCAReport/EntityLinkContext.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/FormattedText.esm.js +94 -0
- package/dist/components/RCA/RCAReport/FormattedText.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/RCAReportView.esm.js +308 -0
- package/dist/components/RCA/RCAReport/RCAReportView.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js +113 -0
- package/dist/components/RCA/RCAReport/sections/AssessmentSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js +272 -0
- package/dist/components/RCA/RCAReport/sections/ChatPanelSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js +48 -0
- package/dist/components/RCA/RCAReport/sections/ExcludedCausesSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js +205 -0
- package/dist/components/RCA/RCAReport/sections/IncidentOverviewSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js +121 -0
- package/dist/components/RCA/RCAReport/sections/InvestigationPathSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js +593 -0
- package/dist/components/RCA/RCAReport/sections/PatchTabContent.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js +35 -0
- package/dist/components/RCA/RCAReport/sections/QuickFixesPanelSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js +54 -0
- package/dist/components/RCA/RCAReport/sections/RecommendationsSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js +526 -0
- package/dist/components/RCA/RCAReport/sections/RootCausesSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js +70 -0
- package/dist/components/RCA/RCAReport/sections/SystemTimelineSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js +54 -0
- package/dist/components/RCA/RCAReport/sections/VisibilityImprovementsSection.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport/styles.esm.js +467 -0
- package/dist/components/RCA/RCAReport/styles.esm.js.map +1 -0
- package/dist/components/RCA/RCAReport.esm.js +109 -0
- package/dist/components/RCA/RCAReport.esm.js.map +1 -0
- package/dist/components/RCA/RCATable.esm.js +140 -0
- package/dist/components/RCA/RCATable.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogEntry.esm.js +182 -0
- package/dist/components/RuntimeLogs/LogEntry.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsActions.esm.js +106 -0
- package/dist/components/RuntimeLogs/LogsActions.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsFilter.esm.js +200 -0
- package/dist/components/RuntimeLogs/LogsFilter.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/LogsTable.esm.js +91 -0
- package/dist/components/RuntimeLogs/LogsTable.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js +220 -0
- package/dist/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js +222 -0
- package/dist/components/RuntimeLogs/ObservabilityRuntimeLogsPage.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/styles.esm.js +256 -0
- package/dist/components/RuntimeLogs/styles.esm.js.map +1 -0
- package/dist/components/RuntimeLogs/types.esm.js +16 -0
- package/dist/components/RuntimeLogs/types.esm.js.map +1 -0
- package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js +280 -0
- package/dist/components/TimeRangeFilter/TimeRangeFilter.esm.js.map +1 -0
- package/dist/components/Traces/ObservabilityTracesPage.esm.js +165 -0
- package/dist/components/Traces/ObservabilityTracesPage.esm.js.map +1 -0
- package/dist/components/Traces/TracesActions.esm.js +37 -0
- package/dist/components/Traces/TracesActions.esm.js.map +1 -0
- package/dist/components/Traces/TracesFilters.esm.js +121 -0
- package/dist/components/Traces/TracesFilters.esm.js.map +1 -0
- package/dist/components/Traces/TracesTable.esm.js +137 -0
- package/dist/components/Traces/TracesTable.esm.js.map +1 -0
- package/dist/components/Traces/WaterfallView.esm.js +567 -0
- package/dist/components/Traces/WaterfallView.esm.js.map +1 -0
- package/dist/components/Traces/styles.esm.js +198 -0
- package/dist/components/Traces/styles.esm.js.map +1 -0
- package/dist/components/Traces/utils.esm.js +19 -0
- package/dist/components/Traces/utils.esm.js.map +1 -0
- package/dist/hooks/useAutoSelectFirstEnvironment.esm.js +25 -0
- package/dist/hooks/useAutoSelectFirstEnvironment.esm.js.map +1 -0
- package/dist/hooks/useComponentAlerts.esm.js +80 -0
- package/dist/hooks/useComponentAlerts.esm.js.map +1 -0
- package/dist/hooks/useDataPlaneNetPolProvider.esm.js +55 -0
- package/dist/hooks/useDataPlaneNetPolProvider.esm.js.map +1 -0
- package/dist/hooks/useDebouncedSearch.esm.js +24 -0
- package/dist/hooks/useDebouncedSearch.esm.js.map +1 -0
- package/dist/hooks/useFilters.esm.js +29 -0
- package/dist/hooks/useFilters.esm.js.map +1 -0
- package/dist/hooks/useFinOpsReport.esm.js +66 -0
- package/dist/hooks/useFinOpsReport.esm.js.map +1 -0
- package/dist/hooks/useFinOpsReports.esm.js +70 -0
- package/dist/hooks/useFinOpsReports.esm.js.map +1 -0
- package/dist/hooks/useGetComponentsByProject.esm.js +57 -0
- package/dist/hooks/useGetComponentsByProject.esm.js.map +1 -0
- package/dist/hooks/useGetEnvironmentsByNamespace.esm.js +53 -0
- package/dist/hooks/useGetEnvironmentsByNamespace.esm.js.map +1 -0
- package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js +40 -0
- package/dist/hooks/useGetNamespaceAndProjectByEntity.esm.js.map +1 -0
- package/dist/hooks/useMetrics.esm.js +107 -0
- package/dist/hooks/useMetrics.esm.js.map +1 -0
- package/dist/hooks/useProjectIncidents.esm.js +111 -0
- package/dist/hooks/useProjectIncidents.esm.js.map +1 -0
- package/dist/hooks/useProjectRuntimeLogs.esm.js +185 -0
- package/dist/hooks/useProjectRuntimeLogs.esm.js.map +1 -0
- package/dist/hooks/useRCAReportByAlert.esm.js +54 -0
- package/dist/hooks/useRCAReportByAlert.esm.js.map +1 -0
- package/dist/hooks/useRCAReports.esm.js +75 -0
- package/dist/hooks/useRCAReports.esm.js.map +1 -0
- package/dist/hooks/useRuntimeLogs.esm.js +147 -0
- package/dist/hooks/useRuntimeLogs.esm.js.map +1 -0
- package/dist/hooks/useSpanDetails.esm.js +71 -0
- package/dist/hooks/useSpanDetails.esm.js.map +1 -0
- package/dist/hooks/useTraceSpans.esm.js +80 -0
- package/dist/hooks/useTraceSpans.esm.js.map +1 -0
- package/dist/hooks/useTraces.esm.js +112 -0
- package/dist/hooks/useTraces.esm.js.map +1 -0
- package/dist/hooks/useUpdateIncident.esm.js +50 -0
- package/dist/hooks/useUpdateIncident.esm.js.map +1 -0
- package/dist/hooks/useUrlFilters.esm.js +63 -0
- package/dist/hooks/useUrlFilters.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForAlerts.esm.js +80 -0
- package/dist/hooks/useUrlFiltersForAlerts.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForIncidents.esm.js +87 -0
- package/dist/hooks/useUrlFiltersForIncidents.esm.js.map +1 -0
- package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js +135 -0
- package/dist/hooks/useUrlFiltersForRuntimeLogs.esm.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +107 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/types.esm.js +18 -0
- package/dist/types.esm.js.map +1 -0
- package/dist/utils/applyResourceChange.esm.js +79 -0
- package/dist/utils/applyResourceChange.esm.js.map +1 -0
- package/dist/utils/urlTimeRange.esm.js +52 -0
- package/dist/utils/urlTimeRange.esm.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Grid, TextField, FormControl, InputLabel, Select, MenuItem, Checkbox, Divider } from '@material-ui/core';
|
|
3
|
+
import { Skeleton } from '@material-ui/lab';
|
|
4
|
+
import { useDebouncedSearch } from '../../hooks/useDebouncedSearch.esm.js';
|
|
5
|
+
import { TimeRangeFilter } from '../TimeRangeFilter/TimeRangeFilter.esm.js';
|
|
6
|
+
import { SELECTED_FIELDS, LogEntryField, LOG_LEVELS } from './types.esm.js';
|
|
7
|
+
|
|
8
|
+
const LogsFilter = ({
|
|
9
|
+
filters,
|
|
10
|
+
onFiltersChange,
|
|
11
|
+
environments,
|
|
12
|
+
environmentsLoading,
|
|
13
|
+
components = [],
|
|
14
|
+
componentsLoading = false,
|
|
15
|
+
disabled = false
|
|
16
|
+
}) => {
|
|
17
|
+
const [searchInput, handleSearchChange] = useDebouncedSearch(
|
|
18
|
+
filters.searchQuery,
|
|
19
|
+
(value) => onFiltersChange({ searchQuery: value })
|
|
20
|
+
);
|
|
21
|
+
const handleEnvironmentChange = (event) => {
|
|
22
|
+
onFiltersChange({ environment: event.target.value });
|
|
23
|
+
};
|
|
24
|
+
const handleComponentChange = (event) => {
|
|
25
|
+
onFiltersChange({ components: event.target.value });
|
|
26
|
+
};
|
|
27
|
+
const handleLogLevelSelectChange = (event) => {
|
|
28
|
+
const value = event.target.value;
|
|
29
|
+
if (value.includes("ALL")) return;
|
|
30
|
+
onFiltersChange({ logLevel: value });
|
|
31
|
+
};
|
|
32
|
+
const handleAllLogLevelsToggle = () => {
|
|
33
|
+
if (filters.logLevel.length === LOG_LEVELS.length) {
|
|
34
|
+
onFiltersChange({ logLevel: [] });
|
|
35
|
+
} else {
|
|
36
|
+
onFiltersChange({ logLevel: [...LOG_LEVELS] });
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const handleSelectedFieldsChange = (event) => {
|
|
40
|
+
let selectedFields = event.target.value;
|
|
41
|
+
if (!selectedFields.includes(LogEntryField.Log)) {
|
|
42
|
+
selectedFields = [...selectedFields, LogEntryField.Log];
|
|
43
|
+
}
|
|
44
|
+
onFiltersChange({
|
|
45
|
+
selectedFields: SELECTED_FIELDS.filter(
|
|
46
|
+
(field) => selectedFields.includes(field)
|
|
47
|
+
)
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
return /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 2, children: [
|
|
51
|
+
/* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 4, children: /* @__PURE__ */ jsx(
|
|
52
|
+
TextField,
|
|
53
|
+
{
|
|
54
|
+
fullWidth: true,
|
|
55
|
+
placeholder: "Search Logs...",
|
|
56
|
+
variant: "outlined",
|
|
57
|
+
value: searchInput,
|
|
58
|
+
onChange: handleSearchChange,
|
|
59
|
+
disabled
|
|
60
|
+
}
|
|
61
|
+
) }),
|
|
62
|
+
components.length > 0 && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(
|
|
63
|
+
FormControl,
|
|
64
|
+
{
|
|
65
|
+
fullWidth: true,
|
|
66
|
+
disabled: disabled || componentsLoading,
|
|
67
|
+
variant: "outlined",
|
|
68
|
+
children: [
|
|
69
|
+
/* @__PURE__ */ jsx(InputLabel, { id: "components-label", children: "Components" }),
|
|
70
|
+
componentsLoading ? /* @__PURE__ */ jsx(Skeleton, { variant: "rect", height: 56 }) : /* @__PURE__ */ jsx(
|
|
71
|
+
Select,
|
|
72
|
+
{
|
|
73
|
+
multiple: true,
|
|
74
|
+
value: filters.components || [],
|
|
75
|
+
onChange: handleComponentChange,
|
|
76
|
+
labelId: "components-label",
|
|
77
|
+
label: "Components",
|
|
78
|
+
renderValue: (selected) => {
|
|
79
|
+
const selectedArray = selected;
|
|
80
|
+
if (selectedArray.length === 0) return "All";
|
|
81
|
+
return selectedArray.join(", ");
|
|
82
|
+
},
|
|
83
|
+
children: components.map((component) => /* @__PURE__ */ jsxs(MenuItem, { value: component.name, children: [
|
|
84
|
+
/* @__PURE__ */ jsx(
|
|
85
|
+
Checkbox,
|
|
86
|
+
{
|
|
87
|
+
checked: (filters.components || []).indexOf(component.name) > -1
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
component.displayName || component.name
|
|
91
|
+
] }, component.name))
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
) }),
|
|
97
|
+
!components.length && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(FormControl, { fullWidth: true, disabled, variant: "outlined", children: [
|
|
98
|
+
/* @__PURE__ */ jsx(InputLabel, { id: "selected-fields-label", children: "Selected Fields" }),
|
|
99
|
+
/* @__PURE__ */ jsx(
|
|
100
|
+
Select,
|
|
101
|
+
{
|
|
102
|
+
multiple: true,
|
|
103
|
+
value: filters.selectedFields,
|
|
104
|
+
onChange: handleSelectedFieldsChange,
|
|
105
|
+
labelId: "selected-fields-label",
|
|
106
|
+
label: "Selected Fields",
|
|
107
|
+
renderValue: (selected) => selected.join(", "),
|
|
108
|
+
children: SELECTED_FIELDS.map((field) => /* @__PURE__ */ jsxs(
|
|
109
|
+
MenuItem,
|
|
110
|
+
{
|
|
111
|
+
value: field,
|
|
112
|
+
disabled: field === LogEntryField.Log,
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
Checkbox,
|
|
116
|
+
{
|
|
117
|
+
checked: filters.selectedFields.includes(field),
|
|
118
|
+
disabled: field === LogEntryField.Log
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
field
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
field
|
|
125
|
+
))
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
] }) }),
|
|
129
|
+
/* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(FormControl, { fullWidth: true, disabled, variant: "outlined", children: [
|
|
130
|
+
/* @__PURE__ */ jsx(InputLabel, { id: "log-levels-label", children: "Log Levels" }),
|
|
131
|
+
/* @__PURE__ */ jsxs(
|
|
132
|
+
Select,
|
|
133
|
+
{
|
|
134
|
+
multiple: true,
|
|
135
|
+
value: filters.logLevel,
|
|
136
|
+
onChange: handleLogLevelSelectChange,
|
|
137
|
+
labelId: "log-levels-label",
|
|
138
|
+
label: "Log Levels",
|
|
139
|
+
renderValue: (selected) => {
|
|
140
|
+
const levels = selected;
|
|
141
|
+
if (levels.length === 0) return "None";
|
|
142
|
+
if (levels.length === LOG_LEVELS.length) return "All";
|
|
143
|
+
return levels.join(", ");
|
|
144
|
+
},
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ jsxs(MenuItem, { value: "ALL", onMouseDown: handleAllLogLevelsToggle, children: [
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
Checkbox,
|
|
149
|
+
{
|
|
150
|
+
checked: filters.logLevel.length === LOG_LEVELS.length,
|
|
151
|
+
indeterminate: filters.logLevel.length > 0 && filters.logLevel.length < LOG_LEVELS.length
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
"All"
|
|
155
|
+
] }),
|
|
156
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
157
|
+
LOG_LEVELS.map((level) => /* @__PURE__ */ jsxs(MenuItem, { value: level, children: [
|
|
158
|
+
/* @__PURE__ */ jsx(Checkbox, { checked: filters.logLevel.includes(level) }),
|
|
159
|
+
level
|
|
160
|
+
] }, level))
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
] }) }),
|
|
165
|
+
/* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsxs(
|
|
166
|
+
FormControl,
|
|
167
|
+
{
|
|
168
|
+
fullWidth: true,
|
|
169
|
+
disabled: disabled || environmentsLoading,
|
|
170
|
+
variant: "outlined",
|
|
171
|
+
children: [
|
|
172
|
+
/* @__PURE__ */ jsx(InputLabel, { id: "environment-label", children: "Environment" }),
|
|
173
|
+
environmentsLoading ? /* @__PURE__ */ jsx(Skeleton, { variant: "rect", height: 56 }) : /* @__PURE__ */ jsx(
|
|
174
|
+
Select,
|
|
175
|
+
{
|
|
176
|
+
value: filters.environment,
|
|
177
|
+
onChange: handleEnvironmentChange,
|
|
178
|
+
labelId: "environment-label",
|
|
179
|
+
label: "Environment",
|
|
180
|
+
children: environments.map((env) => /* @__PURE__ */ jsx(MenuItem, { value: env.name, children: env.displayName || env.name }, env.name))
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
) }),
|
|
186
|
+
/* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 2, children: /* @__PURE__ */ jsx(
|
|
187
|
+
TimeRangeFilter,
|
|
188
|
+
{
|
|
189
|
+
value: filters.timeRange,
|
|
190
|
+
customStartTime: filters.customStartTime,
|
|
191
|
+
customEndTime: filters.customEndTime,
|
|
192
|
+
onChange: onFiltersChange,
|
|
193
|
+
disabled
|
|
194
|
+
}
|
|
195
|
+
) })
|
|
196
|
+
] });
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export { LogsFilter };
|
|
200
|
+
//# sourceMappingURL=LogsFilter.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogsFilter.esm.js","sources":["../../../src/components/RuntimeLogs/LogsFilter.tsx"],"sourcesContent":["import { FC, ChangeEvent } from 'react';\nimport {\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n Checkbox,\n Divider,\n Grid,\n TextField,\n} from '@material-ui/core';\nimport { Skeleton } from '@material-ui/lab';\nimport { Component } from '../../hooks/useGetComponentsByProject';\nimport { useDebouncedSearch } from '../../hooks/useDebouncedSearch';\nimport { type Environment } from '../../types';\nimport { TimeRangeFilter } from '../TimeRangeFilter';\nimport {\n RuntimeLogsFilters,\n LOG_LEVELS,\n SELECTED_FIELDS,\n LogEntryField,\n} from './types';\n\ninterface LogsFilterProps {\n filters: RuntimeLogsFilters;\n onFiltersChange: (filters: Partial<RuntimeLogsFilters>) => void;\n environments: Environment[];\n environmentsLoading: boolean;\n components?: Component[];\n componentsLoading?: boolean;\n disabled?: boolean;\n}\n\nexport const LogsFilter: FC<LogsFilterProps> = ({\n filters,\n onFiltersChange,\n environments,\n environmentsLoading,\n components = [],\n componentsLoading = false,\n disabled = false,\n}) => {\n const [searchInput, handleSearchChange] = useDebouncedSearch(\n filters.searchQuery,\n value => onFiltersChange({ searchQuery: value }),\n );\n\n const handleEnvironmentChange = (event: ChangeEvent<{ value: unknown }>) => {\n onFiltersChange({ environment: event.target.value as string });\n };\n\n const handleComponentChange = (event: ChangeEvent<{ value: unknown }>) => {\n onFiltersChange({ components: event.target.value as string[] });\n };\n\n const handleLogLevelSelectChange = (\n event: ChangeEvent<{ value: unknown }>,\n ) => {\n const value = event.target.value as string[];\n // 'ALL' being present means the \"All\" item was clicked — already handled\n // by onMouseDown on that MenuItem, so skip to avoid overwriting it\n if (value.includes('ALL')) return;\n onFiltersChange({ logLevel: value });\n };\n\n const handleAllLogLevelsToggle = () => {\n if (filters.logLevel.length === LOG_LEVELS.length) {\n onFiltersChange({ logLevel: [] });\n } else {\n onFiltersChange({ logLevel: [...LOG_LEVELS] });\n }\n };\n\n const handleSelectedFieldsChange = (\n event: ChangeEvent<{ value: unknown }>,\n ) => {\n let selectedFields = event.target.value as LogEntryField[];\n // Ensure Log field is always included\n if (!selectedFields.includes(LogEntryField.Log)) {\n selectedFields = [...selectedFields, LogEntryField.Log];\n }\n // sort by the order of the SELECTED_FIELDS array\n // Customizing the order of the selected fields is not supported yet\n onFiltersChange({\n selectedFields: SELECTED_FIELDS.filter(field =>\n selectedFields.includes(field),\n ),\n });\n };\n\n return (\n <Grid container spacing={2}>\n <Grid item xs={12} md={4}>\n <TextField\n fullWidth\n placeholder=\"Search Logs...\"\n variant=\"outlined\"\n value={searchInput}\n onChange={handleSearchChange}\n disabled={disabled}\n />\n </Grid>\n\n {/* Components filter is only shown if there are components - Project level logs */}\n {components.length > 0 && (\n <Grid item xs={12} md={2}>\n <FormControl\n fullWidth\n disabled={disabled || componentsLoading}\n variant=\"outlined\"\n >\n <InputLabel id=\"components-label\">Components</InputLabel>\n {componentsLoading ? (\n <Skeleton variant=\"rect\" height={56} />\n ) : (\n <Select\n multiple\n value={filters.components || []}\n onChange={handleComponentChange}\n labelId=\"components-label\"\n label=\"Components\"\n renderValue={selected => {\n const selectedArray = selected as string[];\n if (selectedArray.length === 0) return 'All';\n return selectedArray.join(', ');\n }}\n >\n {components.map(component => (\n <MenuItem key={component.name} value={component.name}>\n <Checkbox\n checked={\n (filters.components || []).indexOf(component.name) > -1\n }\n />\n {component.displayName || component.name}\n </MenuItem>\n ))}\n </Select>\n )}\n </FormControl>\n </Grid>\n )}\n\n {!components.length && (\n <Grid item xs={12} md={2}>\n <FormControl fullWidth disabled={disabled} variant=\"outlined\">\n <InputLabel id=\"selected-fields-label\">Selected Fields</InputLabel>\n <Select\n multiple\n value={filters.selectedFields}\n onChange={handleSelectedFieldsChange}\n labelId=\"selected-fields-label\"\n label=\"Selected Fields\"\n renderValue={selected => (selected as LogEntryField[]).join(', ')}\n >\n {SELECTED_FIELDS.map((field: LogEntryField) => (\n <MenuItem\n key={field}\n value={field}\n disabled={field === LogEntryField.Log}\n >\n <Checkbox\n checked={filters.selectedFields.includes(field)}\n disabled={field === LogEntryField.Log}\n />\n {field}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n )}\n\n <Grid item xs={12} md={2}>\n <FormControl fullWidth disabled={disabled} variant=\"outlined\">\n <InputLabel id=\"log-levels-label\">Log Levels</InputLabel>\n <Select\n multiple\n value={filters.logLevel}\n onChange={handleLogLevelSelectChange}\n labelId=\"log-levels-label\"\n label=\"Log Levels\"\n renderValue={selected => {\n const levels = selected as string[];\n if (levels.length === 0) return 'None';\n if (levels.length === LOG_LEVELS.length) return 'All';\n return levels.join(', ');\n }}\n >\n <MenuItem value=\"ALL\" onMouseDown={handleAllLogLevelsToggle}>\n <Checkbox\n checked={filters.logLevel.length === LOG_LEVELS.length}\n indeterminate={\n filters.logLevel.length > 0 &&\n filters.logLevel.length < LOG_LEVELS.length\n }\n />\n All\n </MenuItem>\n <Divider />\n {LOG_LEVELS.map(level => (\n <MenuItem key={level} value={level}>\n <Checkbox checked={filters.logLevel.includes(level)} />\n {level}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n\n <Grid item xs={12} md={2}>\n <FormControl\n fullWidth\n disabled={disabled || environmentsLoading}\n variant=\"outlined\"\n >\n <InputLabel id=\"environment-label\">Environment</InputLabel>\n {environmentsLoading ? (\n <Skeleton variant=\"rect\" height={56} />\n ) : (\n <Select\n value={filters.environment}\n onChange={handleEnvironmentChange}\n labelId=\"environment-label\"\n label=\"Environment\"\n >\n {environments.map(env => (\n <MenuItem key={env.name} value={env.name}>\n {env.displayName || env.name}\n </MenuItem>\n ))}\n </Select>\n )}\n </FormControl>\n </Grid>\n\n <Grid item xs={12} md={2}>\n <TimeRangeFilter\n value={filters.timeRange}\n customStartTime={filters.customStartTime}\n customEndTime={filters.customEndTime}\n onChange={onFiltersChange}\n disabled={disabled}\n />\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useEffect, useCallback } from 'react';
|
|
3
|
+
import { Paper, Box, Table, TableHead, TableRow, TableCell, TableBody, CircularProgress, Typography } from '@material-ui/core';
|
|
4
|
+
import { Skeleton } from '@material-ui/lab';
|
|
5
|
+
import { LogEntryField } from './types.esm.js';
|
|
6
|
+
import { LogEntry } from './LogEntry.esm.js';
|
|
7
|
+
import { useLogsTableStyles } from './styles.esm.js';
|
|
8
|
+
|
|
9
|
+
const LogsTable = ({
|
|
10
|
+
selectedFields,
|
|
11
|
+
logs,
|
|
12
|
+
loading,
|
|
13
|
+
hasMore,
|
|
14
|
+
loadingRef,
|
|
15
|
+
environmentName,
|
|
16
|
+
projectName,
|
|
17
|
+
componentName,
|
|
18
|
+
renderRowAction
|
|
19
|
+
}) => {
|
|
20
|
+
const classes = useLogsTableStyles();
|
|
21
|
+
const logsRef = useRef(logs);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
logsRef.current = logs;
|
|
24
|
+
}, [logs]);
|
|
25
|
+
const getLogsSnapshot = useCallback(() => logsRef.current, []);
|
|
26
|
+
const totalColumns = selectedFields.length;
|
|
27
|
+
const renderLoadingSkeletons = () => {
|
|
28
|
+
return Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
29
|
+
selectedFields.includes(LogEntryField.Timestamp) && /* @__PURE__ */ jsx(TableCell, { width: "15%", children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) }),
|
|
30
|
+
selectedFields.includes(LogEntryField.LogLevel) && /* @__PURE__ */ jsx(TableCell, { width: "10%", children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) }),
|
|
31
|
+
selectedFields.includes(LogEntryField.ComponentName) && /* @__PURE__ */ jsx(TableCell, { width: "15%", children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) }),
|
|
32
|
+
selectedFields.includes(LogEntryField.Log) && /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "100%" }) })
|
|
33
|
+
] }, `skeleton-${index}`));
|
|
34
|
+
};
|
|
35
|
+
const renderEmptyState = () => {
|
|
36
|
+
if (loading) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: totalColumns, children: /* @__PURE__ */ jsxs(Box, { className: classes.emptyState, children: [
|
|
40
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "No logs found" }),
|
|
41
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: "Try adjusting your filters or time range to see more logs." })
|
|
42
|
+
] }) }) });
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ jsx(Paper, { className: classes.tablePaper, children: /* @__PURE__ */ jsx(Box, { className: classes.tableContainer, children: /* @__PURE__ */ jsxs(Table, { className: classes.table, stickyHeader: true, children: [
|
|
45
|
+
/* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { children: selectedFields.map((field) => {
|
|
46
|
+
let width;
|
|
47
|
+
if (field === LogEntryField.Timestamp) {
|
|
48
|
+
width = "15%";
|
|
49
|
+
} else if (field === LogEntryField.LogLevel) {
|
|
50
|
+
width = "10%";
|
|
51
|
+
} else if (field === LogEntryField.ComponentName) {
|
|
52
|
+
width = "15%";
|
|
53
|
+
} else {
|
|
54
|
+
width = selectedFields.includes(LogEntryField.ComponentName) ? "60%" : "75%";
|
|
55
|
+
}
|
|
56
|
+
return /* @__PURE__ */ jsx(
|
|
57
|
+
TableCell,
|
|
58
|
+
{
|
|
59
|
+
className: classes.headerCell,
|
|
60
|
+
width,
|
|
61
|
+
children: field
|
|
62
|
+
},
|
|
63
|
+
field
|
|
64
|
+
);
|
|
65
|
+
}) }) }),
|
|
66
|
+
/* @__PURE__ */ jsxs(TableBody, { children: [
|
|
67
|
+
logs.length === 0 && !loading && renderEmptyState(),
|
|
68
|
+
logs.length === 0 && loading && renderLoadingSkeletons(),
|
|
69
|
+
logs.map((log, index) => /* @__PURE__ */ jsx(
|
|
70
|
+
LogEntry,
|
|
71
|
+
{
|
|
72
|
+
log,
|
|
73
|
+
selectedFields,
|
|
74
|
+
environmentName,
|
|
75
|
+
projectName,
|
|
76
|
+
componentName,
|
|
77
|
+
getLogsSnapshot,
|
|
78
|
+
renderRowAction
|
|
79
|
+
},
|
|
80
|
+
`${log.timestamp}-${index}`
|
|
81
|
+
)),
|
|
82
|
+
hasMore && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: totalColumns, children: /* @__PURE__ */ jsx("div", { className: classes.loadingContainer, ref: loadingRef, children: loading ? /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", children: [
|
|
83
|
+
/* @__PURE__ */ jsx(CircularProgress, { size: 20 }),
|
|
84
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", style: { marginLeft: 8 }, children: "Loading more logs..." })
|
|
85
|
+
] }) : /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "Scroll to load more logs" }) }) }) })
|
|
86
|
+
] })
|
|
87
|
+
] }) }) });
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export { LogsTable };
|
|
91
|
+
//# sourceMappingURL=LogsTable.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogsTable.esm.js","sources":["../../../src/components/RuntimeLogs/LogsTable.tsx"],"sourcesContent":["import { RefObject, FC, useCallback, useEffect, useRef } from 'react';\nimport {\n Table,\n TableHead,\n TableBody,\n TableRow,\n TableCell,\n Paper,\n Box,\n Typography,\n CircularProgress,\n} from '@material-ui/core';\nimport { Skeleton } from '@material-ui/lab';\nimport { LogEntryField, LogEntry as LogEntryType } from './types';\nimport { LogEntry, RenderLogRowAction } from './LogEntry';\nimport { useLogsTableStyles } from './styles';\n\ninterface LogsTableProps {\n selectedFields: LogEntryField[];\n logs: LogEntryType[];\n loading: boolean;\n hasMore: boolean;\n loadingRef: RefObject<HTMLDivElement>;\n environmentName?: string;\n projectName?: string;\n componentName?: string;\n renderRowAction?: RenderLogRowAction;\n}\n\nexport const LogsTable: FC<LogsTableProps> = ({\n selectedFields,\n logs,\n loading,\n hasMore,\n loadingRef,\n environmentName,\n projectName,\n componentName,\n renderRowAction,\n}) => {\n const classes = useLogsTableStyles();\n\n // Ref-backed snapshot accessor so per-row buttons can read the\n // *current* logs list without their parent component re-rendering\n // every time a new log batch arrives. Each LogEntry receives a\n // stable callback reference; only the rows whose own props change\n // re-render. The ref is updated after every render so the closure\n // always returns the freshest list.\n const logsRef = useRef<LogEntryType[]>(logs);\n useEffect(() => {\n logsRef.current = logs;\n }, [logs]);\n const getLogsSnapshot = useCallback(() => logsRef.current, []);\n\n const totalColumns = selectedFields.length;\n const renderLoadingSkeletons = () => {\n return Array.from({ length: 5 }).map((_, index) => (\n <TableRow key={`skeleton-${index}`}>\n {selectedFields.includes(LogEntryField.Timestamp) && (\n <TableCell width=\"15%\">\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n {selectedFields.includes(LogEntryField.LogLevel) && (\n <TableCell width=\"10%\">\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n {selectedFields.includes(LogEntryField.ComponentName) && (\n <TableCell width=\"15%\">\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n {selectedFields.includes(LogEntryField.Log) && (\n <TableCell>\n <Skeleton variant=\"text\" width=\"100%\" />\n </TableCell>\n )}\n </TableRow>\n ));\n };\n\n const renderEmptyState = () => {\n if (loading) {\n return null;\n }\n\n return (\n <TableRow>\n <TableCell colSpan={totalColumns}>\n <Box className={classes.emptyState}>\n <Typography variant=\"h6\" gutterBottom>\n No logs found\n </Typography>\n <Typography variant=\"body2\">\n Try adjusting your filters or time range to see more logs.\n </Typography>\n </Box>\n </TableCell>\n </TableRow>\n );\n };\n\n return (\n <Paper className={classes.tablePaper}>\n <Box className={classes.tableContainer}>\n <Table className={classes.table} stickyHeader>\n <TableHead>\n <TableRow>\n {selectedFields.map(field => {\n let width: string | undefined;\n\n if (field === LogEntryField.Timestamp) {\n width = '15%';\n } else if (field === LogEntryField.LogLevel) {\n width = '10%';\n } else if (field === LogEntryField.ComponentName) {\n width = '15%';\n } else {\n width = selectedFields.includes(LogEntryField.ComponentName)\n ? '60%'\n : '75%';\n }\n\n return (\n <TableCell\n key={field}\n className={classes.headerCell}\n width={width}\n >\n {field}\n </TableCell>\n );\n })}\n </TableRow>\n </TableHead>\n <TableBody>\n {logs.length === 0 && !loading && renderEmptyState()}\n\n {logs.length === 0 && loading && renderLoadingSkeletons()}\n\n {logs.map((log, index) => (\n <LogEntry\n key={`${log.timestamp}-${index}`}\n log={log}\n selectedFields={selectedFields}\n environmentName={environmentName}\n projectName={projectName}\n componentName={componentName}\n getLogsSnapshot={getLogsSnapshot}\n renderRowAction={renderRowAction}\n />\n ))}\n\n {hasMore && (\n <TableRow>\n <TableCell colSpan={totalColumns}>\n <div className={classes.loadingContainer} ref={loadingRef}>\n {loading ? (\n <Box display=\"flex\" alignItems=\"center\">\n <CircularProgress size={20} />\n <Typography variant=\"body2\" style={{ marginLeft: 8 }}>\n Loading more logs...\n </Typography>\n </Box>\n ) : (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Scroll to load more logs\n </Typography>\n )}\n </div>\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </Box>\n </Paper>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo, useState, useRef, useEffect } from 'react';
|
|
3
|
+
import { Box, Typography, Button } from '@material-ui/core';
|
|
4
|
+
import { Progress } from '@backstage/core-components';
|
|
5
|
+
import { Alert } from '@material-ui/lab';
|
|
6
|
+
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
7
|
+
import { CHOREO_ANNOTATIONS } from '@openchoreo/backstage-plugin-common';
|
|
8
|
+
import { LogsFilter } from './LogsFilter.esm.js';
|
|
9
|
+
import { LogsTable } from './LogsTable.esm.js';
|
|
10
|
+
import { LogsActions } from './LogsActions.esm.js';
|
|
11
|
+
import '@backstage/core-plugin-api';
|
|
12
|
+
import { useGetEnvironmentsByNamespace } from '../../hooks/useGetEnvironmentsByNamespace.esm.js';
|
|
13
|
+
import 'react-router-dom';
|
|
14
|
+
import '../../utils/urlTimeRange.esm.js';
|
|
15
|
+
import '../../api/ObservabilityApi.esm.js';
|
|
16
|
+
import { useLogsPermission, ForbiddenState, useInfiniteScroll } from '@openchoreo/backstage-plugin-react';
|
|
17
|
+
import { useGetComponentsByProject } from '../../hooks/useGetComponentsByProject.esm.js';
|
|
18
|
+
import { useProjectRuntimeLogs } from '../../hooks/useProjectRuntimeLogs.esm.js';
|
|
19
|
+
import { useUrlFiltersForRuntimeLogs } from '../../hooks/useUrlFiltersForRuntimeLogs.esm.js';
|
|
20
|
+
import '../../api/RCAAgentApi.esm.js';
|
|
21
|
+
import '../../api/FinOpsAgentApi.esm.js';
|
|
22
|
+
import { useRuntimeLogsStyles } from './styles.esm.js';
|
|
23
|
+
import { LogEntryField } from './types.esm.js';
|
|
24
|
+
|
|
25
|
+
const ObservabilityProjectRuntimeLogsContent = ({
|
|
26
|
+
renderRowAction
|
|
27
|
+
}) => {
|
|
28
|
+
const classes = useRuntimeLogsStyles();
|
|
29
|
+
const { entity } = useEntity();
|
|
30
|
+
const namespace = entity.metadata.annotations?.[CHOREO_ANNOTATIONS.NAMESPACE] || "";
|
|
31
|
+
const projectName = entity.metadata.name || "";
|
|
32
|
+
const {
|
|
33
|
+
environments,
|
|
34
|
+
loading: environmentsLoading,
|
|
35
|
+
error: environmentsError
|
|
36
|
+
} = useGetEnvironmentsByNamespace(namespace, projectName);
|
|
37
|
+
const {
|
|
38
|
+
components,
|
|
39
|
+
loading: componentsLoading,
|
|
40
|
+
error: componentsError
|
|
41
|
+
} = useGetComponentsByProject(entity);
|
|
42
|
+
const { filters, updateFilters } = useUrlFiltersForRuntimeLogs({
|
|
43
|
+
environments
|
|
44
|
+
});
|
|
45
|
+
const selectedEnvironment = environments.find(
|
|
46
|
+
(env) => env.name === filters.environment
|
|
47
|
+
);
|
|
48
|
+
const tableSelectedFields = useMemo(() => {
|
|
49
|
+
const withoutComponent = filters.selectedFields.filter(
|
|
50
|
+
(field) => field !== LogEntryField.ComponentName
|
|
51
|
+
);
|
|
52
|
+
const logIndex = withoutComponent.indexOf(LogEntryField.Log);
|
|
53
|
+
if (logIndex === -1) {
|
|
54
|
+
return [...withoutComponent, LogEntryField.ComponentName];
|
|
55
|
+
}
|
|
56
|
+
return [
|
|
57
|
+
...withoutComponent.slice(0, logIndex),
|
|
58
|
+
LogEntryField.ComponentName,
|
|
59
|
+
...withoutComponent.slice(logIndex)
|
|
60
|
+
];
|
|
61
|
+
}, [filters.selectedFields]);
|
|
62
|
+
const [lastUpdated, setLastUpdated] = useState(/* @__PURE__ */ new Date());
|
|
63
|
+
const {
|
|
64
|
+
logs,
|
|
65
|
+
loading: logsLoading,
|
|
66
|
+
error: logsError,
|
|
67
|
+
totalCount,
|
|
68
|
+
hasMore,
|
|
69
|
+
fetchLogs,
|
|
70
|
+
loadMore,
|
|
71
|
+
refresh,
|
|
72
|
+
clearLogs
|
|
73
|
+
} = useProjectRuntimeLogs(filters, entity, {
|
|
74
|
+
environmentName: filters.environment,
|
|
75
|
+
namespaceName: namespace,
|
|
76
|
+
projectName,
|
|
77
|
+
limit: 50
|
|
78
|
+
});
|
|
79
|
+
const { loadingRef } = useInfiniteScroll(loadMore, hasMore, logsLoading);
|
|
80
|
+
const previousFiltersRef = useRef(null);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
const currentFilters = {
|
|
83
|
+
environment: filters.environment,
|
|
84
|
+
logLevel: filters.logLevel,
|
|
85
|
+
timeRange: filters.timeRange,
|
|
86
|
+
customStartTime: filters.customStartTime,
|
|
87
|
+
customEndTime: filters.customEndTime,
|
|
88
|
+
searchQuery: filters.searchQuery,
|
|
89
|
+
sortOrder: filters.sortOrder,
|
|
90
|
+
components: filters.components || []
|
|
91
|
+
};
|
|
92
|
+
const filtersChanged = previousFiltersRef.current === null || JSON.stringify(previousFiltersRef.current) !== JSON.stringify(currentFilters);
|
|
93
|
+
if (filters.environment && selectedEnvironment && namespace && projectName && filtersChanged) {
|
|
94
|
+
if (filters.logLevel.length === 0) {
|
|
95
|
+
clearLogs();
|
|
96
|
+
} else {
|
|
97
|
+
fetchLogs(true);
|
|
98
|
+
setLastUpdated(/* @__PURE__ */ new Date());
|
|
99
|
+
}
|
|
100
|
+
previousFiltersRef.current = currentFilters;
|
|
101
|
+
}
|
|
102
|
+
}, [
|
|
103
|
+
filters.environment,
|
|
104
|
+
filters.logLevel,
|
|
105
|
+
filters.timeRange,
|
|
106
|
+
filters.customStartTime,
|
|
107
|
+
filters.customEndTime,
|
|
108
|
+
filters.searchQuery,
|
|
109
|
+
filters.sortOrder,
|
|
110
|
+
filters.components,
|
|
111
|
+
fetchLogs,
|
|
112
|
+
clearLogs,
|
|
113
|
+
selectedEnvironment,
|
|
114
|
+
namespace,
|
|
115
|
+
projectName
|
|
116
|
+
]);
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
if (!logsLoading) {
|
|
119
|
+
setLastUpdated(/* @__PURE__ */ new Date());
|
|
120
|
+
}
|
|
121
|
+
}, [logsLoading]);
|
|
122
|
+
const handleRefresh = () => {
|
|
123
|
+
refresh();
|
|
124
|
+
setLastUpdated(/* @__PURE__ */ new Date());
|
|
125
|
+
};
|
|
126
|
+
const handleFiltersChange = (newFilters) => {
|
|
127
|
+
updateFilters(newFilters);
|
|
128
|
+
};
|
|
129
|
+
const renderError = (error) => {
|
|
130
|
+
const isObservabilityDisabled = error.includes(
|
|
131
|
+
"Observability is not enabled"
|
|
132
|
+
);
|
|
133
|
+
return /* @__PURE__ */ jsxs(
|
|
134
|
+
Alert,
|
|
135
|
+
{
|
|
136
|
+
severity: isObservabilityDisabled ? "info" : "error",
|
|
137
|
+
className: classes.errorContainer,
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body1", children: isObservabilityDisabled ? "Observability is not enabled for this project in the current environment. Enable observability to view runtime logs." : error }),
|
|
140
|
+
!isObservabilityDisabled && /* @__PURE__ */ jsx(Button, { onClick: handleRefresh, color: "inherit", size: "small", children: "Retry" })
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
if (environmentsError) {
|
|
146
|
+
return /* @__PURE__ */ jsx(Box, { children: renderError(environmentsError) });
|
|
147
|
+
}
|
|
148
|
+
if (componentsError) {
|
|
149
|
+
return /* @__PURE__ */ jsx(Box, { children: renderError(componentsError) });
|
|
150
|
+
}
|
|
151
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
LogsFilter,
|
|
154
|
+
{
|
|
155
|
+
filters,
|
|
156
|
+
onFiltersChange: handleFiltersChange,
|
|
157
|
+
environments,
|
|
158
|
+
environmentsLoading,
|
|
159
|
+
components,
|
|
160
|
+
componentsLoading,
|
|
161
|
+
disabled: logsLoading
|
|
162
|
+
}
|
|
163
|
+
),
|
|
164
|
+
logsError && renderError(logsError),
|
|
165
|
+
!filters.environment && !environmentsLoading && environments.length === 0 && /* @__PURE__ */ jsx(Alert, { severity: "info", className: classes.errorContainer, children: /* @__PURE__ */ jsx(Typography, { variant: "body1", children: "No environments found for this project." }) }),
|
|
166
|
+
filters.environment && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
167
|
+
/* @__PURE__ */ jsx(
|
|
168
|
+
LogsActions,
|
|
169
|
+
{
|
|
170
|
+
totalCount,
|
|
171
|
+
disabled: logsLoading || !filters.environment,
|
|
172
|
+
onRefresh: handleRefresh,
|
|
173
|
+
filters,
|
|
174
|
+
onFiltersChange: handleFiltersChange,
|
|
175
|
+
lastUpdated
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
/* @__PURE__ */ jsx(
|
|
179
|
+
LogsTable,
|
|
180
|
+
{
|
|
181
|
+
selectedFields: tableSelectedFields,
|
|
182
|
+
logs,
|
|
183
|
+
loading: logsLoading,
|
|
184
|
+
hasMore,
|
|
185
|
+
loadingRef,
|
|
186
|
+
environmentName: selectedEnvironment?.displayName || selectedEnvironment?.name,
|
|
187
|
+
projectName,
|
|
188
|
+
renderRowAction
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
] })
|
|
192
|
+
] });
|
|
193
|
+
};
|
|
194
|
+
const ObservabilityProjectRuntimeLogsPage = ({
|
|
195
|
+
renderRowAction
|
|
196
|
+
}) => {
|
|
197
|
+
const {
|
|
198
|
+
canViewLogs,
|
|
199
|
+
loading: permissionLoading,
|
|
200
|
+
deniedTooltip,
|
|
201
|
+
permissionName
|
|
202
|
+
} = useLogsPermission();
|
|
203
|
+
if (permissionLoading) {
|
|
204
|
+
return /* @__PURE__ */ jsx(Progress, {});
|
|
205
|
+
}
|
|
206
|
+
if (!canViewLogs) {
|
|
207
|
+
return /* @__PURE__ */ jsx(
|
|
208
|
+
ForbiddenState,
|
|
209
|
+
{
|
|
210
|
+
message: deniedTooltip,
|
|
211
|
+
permissionName,
|
|
212
|
+
variant: "fullpage"
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
return /* @__PURE__ */ jsx(ObservabilityProjectRuntimeLogsContent, { renderRowAction });
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
export { ObservabilityProjectRuntimeLogsPage };
|
|
220
|
+
//# sourceMappingURL=ObservabilityProjectRuntimeLogsPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObservabilityProjectRuntimeLogsPage.esm.js","sources":["../../../src/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport { Box, Typography, Button } from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { Alert } from '@material-ui/lab';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { CHOREO_ANNOTATIONS } from '@openchoreo/backstage-plugin-common';\nimport { LogsFilter } from './LogsFilter';\nimport { LogsTable } from './LogsTable';\nimport { LogsActions } from './LogsActions';\nimport {\n useGetEnvironmentsByNamespace,\n useGetComponentsByProject,\n useProjectRuntimeLogs,\n useUrlFiltersForRuntimeLogs,\n} from '../../hooks';\nimport {\n useInfiniteScroll,\n useLogsPermission,\n ForbiddenState,\n} from '@openchoreo/backstage-plugin-react';\nimport { useRuntimeLogsStyles } from './styles';\nimport { LogEntryField } from './types';\nimport type { RenderLogRowAction } from './LogEntry';\n\nexport interface ObservabilityProjectRuntimeLogsPageProps {\n renderRowAction?: RenderLogRowAction;\n}\n\nconst ObservabilityProjectRuntimeLogsContent = ({\n renderRowAction,\n}: ObservabilityProjectRuntimeLogsPageProps) => {\n const classes = useRuntimeLogsStyles();\n const { entity } = useEntity();\n\n const namespace =\n entity.metadata.annotations?.[CHOREO_ANNOTATIONS.NAMESPACE] || '';\n const projectName = entity.metadata.name || '';\n\n const {\n environments,\n loading: environmentsLoading,\n error: environmentsError,\n } = useGetEnvironmentsByNamespace(namespace, projectName);\n\n const {\n components,\n loading: componentsLoading,\n error: componentsError,\n } = useGetComponentsByProject(entity);\n\n const { filters, updateFilters } = useUrlFiltersForRuntimeLogs({\n environments,\n });\n\n const selectedEnvironment = environments.find(\n env => env.name === filters.environment,\n );\n const tableSelectedFields = useMemo(() => {\n const withoutComponent = filters.selectedFields.filter(\n field => field !== LogEntryField.ComponentName,\n );\n const logIndex = withoutComponent.indexOf(LogEntryField.Log);\n\n if (logIndex === -1) {\n return [...withoutComponent, LogEntryField.ComponentName];\n }\n\n return [\n ...withoutComponent.slice(0, logIndex),\n LogEntryField.ComponentName,\n ...withoutComponent.slice(logIndex),\n ];\n }, [filters.selectedFields]);\n\n const [lastUpdated, setLastUpdated] = useState<Date>(new Date());\n\n const {\n logs,\n loading: logsLoading,\n error: logsError,\n totalCount,\n hasMore,\n fetchLogs,\n loadMore,\n refresh,\n clearLogs,\n } = useProjectRuntimeLogs(filters, entity, {\n environmentName: filters.environment,\n namespaceName: namespace,\n projectName,\n limit: 50,\n });\n\n const { loadingRef } = useInfiniteScroll(loadMore, hasMore, logsLoading);\n\n const previousFiltersRef = useRef<{\n environment: string;\n logLevel: string[];\n timeRange: string;\n customStartTime?: string;\n customEndTime?: string;\n searchQuery?: string;\n sortOrder?: 'asc' | 'desc';\n components: string[];\n } | null>(null);\n\n useEffect(() => {\n const currentFilters = {\n environment: filters.environment,\n logLevel: filters.logLevel,\n timeRange: filters.timeRange,\n customStartTime: filters.customStartTime,\n customEndTime: filters.customEndTime,\n searchQuery: filters.searchQuery,\n sortOrder: filters.sortOrder,\n components: filters.components || [],\n };\n\n const filtersChanged =\n previousFiltersRef.current === null ||\n JSON.stringify(previousFiltersRef.current) !==\n JSON.stringify(currentFilters);\n\n if (\n filters.environment &&\n selectedEnvironment &&\n namespace &&\n projectName &&\n filtersChanged\n ) {\n if (filters.logLevel.length === 0) {\n clearLogs();\n } else {\n fetchLogs(true);\n setLastUpdated(new Date());\n }\n previousFiltersRef.current = currentFilters;\n }\n }, [\n filters.environment,\n filters.logLevel,\n filters.timeRange,\n filters.customStartTime,\n filters.customEndTime,\n filters.searchQuery,\n filters.sortOrder,\n filters.components,\n fetchLogs,\n clearLogs,\n selectedEnvironment,\n namespace,\n projectName,\n ]);\n\n useEffect(() => {\n if (!logsLoading) {\n setLastUpdated(new Date());\n }\n }, [logsLoading]);\n\n const handleRefresh = () => {\n refresh();\n setLastUpdated(new Date());\n };\n\n const handleFiltersChange = (newFilters: Partial<typeof filters>) => {\n updateFilters(newFilters);\n };\n\n const renderError = (error: string) => {\n const isObservabilityDisabled = error.includes(\n 'Observability is not enabled',\n );\n\n return (\n <Alert\n severity={isObservabilityDisabled ? 'info' : 'error'}\n className={classes.errorContainer}\n >\n <Typography variant=\"body1\">\n {isObservabilityDisabled\n ? 'Observability is not enabled for this project in the current environment. Enable observability to view runtime logs.'\n : error}\n </Typography>\n {!isObservabilityDisabled && (\n <Button onClick={handleRefresh} color=\"inherit\" size=\"small\">\n Retry\n </Button>\n )}\n </Alert>\n );\n };\n\n if (environmentsError) {\n return <Box>{renderError(environmentsError)}</Box>;\n }\n\n if (componentsError) {\n return <Box>{renderError(componentsError)}</Box>;\n }\n\n return (\n <Box>\n <LogsFilter\n filters={filters}\n onFiltersChange={handleFiltersChange}\n environments={environments}\n environmentsLoading={environmentsLoading}\n components={components}\n componentsLoading={componentsLoading}\n disabled={logsLoading}\n />\n\n {logsError && renderError(logsError)}\n\n {!filters.environment &&\n !environmentsLoading &&\n environments.length === 0 && (\n <Alert severity=\"info\" className={classes.errorContainer}>\n <Typography variant=\"body1\">\n No environments found for this project.\n </Typography>\n </Alert>\n )}\n\n {filters.environment && (\n <>\n <LogsActions\n totalCount={totalCount}\n disabled={logsLoading || !filters.environment}\n onRefresh={handleRefresh}\n filters={filters}\n onFiltersChange={handleFiltersChange}\n lastUpdated={lastUpdated}\n />\n\n <LogsTable\n selectedFields={tableSelectedFields}\n logs={logs}\n loading={logsLoading}\n hasMore={hasMore}\n loadingRef={loadingRef}\n environmentName={\n selectedEnvironment?.displayName || selectedEnvironment?.name\n }\n projectName={projectName}\n renderRowAction={renderRowAction}\n />\n </>\n )}\n </Box>\n );\n};\n\nexport const ObservabilityProjectRuntimeLogsPage = ({\n renderRowAction,\n}: ObservabilityProjectRuntimeLogsPageProps) => {\n const {\n canViewLogs,\n loading: permissionLoading,\n deniedTooltip,\n permissionName,\n } = useLogsPermission();\n\n if (permissionLoading) {\n return <Progress />;\n }\n\n if (!canViewLogs) {\n return (\n <ForbiddenState\n message={deniedTooltip}\n permissionName={permissionName}\n variant=\"fullpage\"\n />\n );\n }\n\n return (\n <ObservabilityProjectRuntimeLogsContent renderRowAction={renderRowAction} />\n );\n};\n"],"names":[],"mappings":"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"}
|