diff --git a/frontend/endpoints/describe.go b/frontend/endpoints/describe.go index 17bc71c71..c57fec891 100644 --- a/frontend/endpoints/describe.go +++ b/frontend/endpoints/describe.go @@ -21,11 +21,6 @@ func DescribeOdigos(c *gin.Context) { // construct the http response code based on the status of the odigos returnCode := 200 - if desc.HasErrors { - returnCode = 500 - } else if !desc.IsSettled { - returnCode = 202 - } // Check for the Accept header acceptHeader := c.GetHeader("Accept") diff --git a/frontend/webapp/assets/icons/general/describe.svg b/frontend/webapp/assets/icons/general/describe.svg new file mode 100644 index 000000000..25088b139 --- /dev/null +++ b/frontend/webapp/assets/icons/general/describe.svg @@ -0,0 +1 @@ + paper Created with Sketch. \ No newline at end of file diff --git a/frontend/webapp/assets/icons/general/index.ts b/frontend/webapp/assets/icons/general/index.ts index 9e731bb54..ecceee6ff 100644 --- a/frontend/webapp/assets/icons/general/index.ts +++ b/frontend/webapp/assets/icons/general/index.ts @@ -1,4 +1,7 @@ import Funnel from './funnel.svg'; import FunnelFocus from './funnel-focus.svg'; import PayloadCollectionIcon from './payload-collection.svg'; -export { Funnel, FunnelFocus, PayloadCollectionIcon }; +import Describe from './describe.svg'; +import Refresh from './refresh.svg'; + +export { Funnel, FunnelFocus, PayloadCollectionIcon, Describe, Refresh }; diff --git a/frontend/webapp/assets/icons/general/refresh.svg b/frontend/webapp/assets/icons/general/refresh.svg new file mode 100644 index 000000000..7db42c18a --- /dev/null +++ b/frontend/webapp/assets/icons/general/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/webapp/components/overview/overview.header/overview.header.tsx b/frontend/webapp/components/overview/overview.header/overview.header.tsx index 5f845ef5d..90d72948b 100644 --- a/frontend/webapp/components/overview/overview.header/overview.header.tsx +++ b/frontend/webapp/components/overview/overview.header/overview.header.tsx @@ -4,6 +4,7 @@ import styled from 'styled-components'; import { KeyvalText } from '@/design.system'; import { NotificationList } from '@/components'; import { BackIcon } from '@keyval-dev/design-system'; +import { OdigosDescriptionDrawer } from '@/containers'; export interface OverviewHeaderProps { title?: string; @@ -51,8 +52,10 @@ export function OverviewHeader({ title, onBackClick }: OverviewHeaderProps) { {title} - - {!onBackClick && } +
+ {!onBackClick && } + {title === 'Overview' && } +
); } diff --git a/frontend/webapp/containers/main/overview/data.flow/index.tsx b/frontend/webapp/containers/main/overview/data.flow/index.tsx index 730fefe32..7434a18a7 100644 --- a/frontend/webapp/containers/main/overview/data.flow/index.tsx +++ b/frontend/webapp/containers/main/overview/data.flow/index.tsx @@ -46,7 +46,7 @@ export function DataFlowContainer() { const { destinationList, refetchDestinations } = useDestinations(); const useSearch = useSearchParams(); - const intervalId = useRef(); + const intervalId = useRef(); const { metrics } = useOverviewMetrics(); diff --git a/frontend/webapp/containers/main/overview/index.ts b/frontend/webapp/containers/main/overview/index.ts index a5200cb12..0d86d93bf 100644 --- a/frontend/webapp/containers/main/overview/index.ts +++ b/frontend/webapp/containers/main/overview/index.ts @@ -1 +1,2 @@ export * from './data.flow'; +export * from './odigos-describe'; diff --git a/frontend/webapp/containers/main/overview/odigos-describe/index.tsx b/frontend/webapp/containers/main/overview/odigos-describe/index.tsx new file mode 100644 index 000000000..3ed8eadab --- /dev/null +++ b/frontend/webapp/containers/main/overview/odigos-describe/index.tsx @@ -0,0 +1,248 @@ +'use client'; +import React, { useEffect, useState } from 'react'; +import { Describe, Refresh } from '@/assets'; // Assume RefreshIcon is the refresh icon component +import theme from '@/styles/palette'; +import { useDescribe } from '@/hooks'; +import styled from 'styled-components'; +import { Drawer, KeyvalText } from '@/design.system'; + +interface OdigosDescriptionDrawerProps {} + +export const OdigosDescriptionDrawer: React.FC< + OdigosDescriptionDrawerProps +> = ({}) => { + const [isOpen, setDrawerOpen] = useState(false); + + const [badgeStatus, setBadgeStatus] = useState< + 'error' | 'transitioning' | 'success' + >('success'); + + const toggleDrawer = () => setDrawerOpen(!isOpen); + + const { odigosDescription, isOdigosLoading, refetchOdigosDescription } = + useDescribe(); + + useEffect(() => { + if (odigosDescription) { + const statuses = extractStatuses(odigosDescription); + if (statuses.includes('error')) setBadgeStatus('error'); + else if (statuses.includes('transitioning')) + setBadgeStatus('transitioning'); + else setBadgeStatus('success'); + } + }, [odigosDescription]); + + useEffect(() => { + refetchOdigosDescription(); + }, [refetchOdigosDescription]); + + return ( + <> + + + {!isOdigosLoading && ( + + + {badgeStatus === 'transitioning' + ? '...' + : badgeStatus === 'error' + ? '!' + : ''} + + + )} + + + {isOpen && ( + setDrawerOpen(false)} + position="right" + width="fit-content" + > + {isOdigosLoading ? ( + Loading description... + ) : ( + + {odigosDescription + ? formatOdigosDescription( + odigosDescription, + refetchOdigosDescription + ) + : 'No description available.'} + + )} + + )} + + ); +}; + +// Function to extract statuses from the odigosDescription response +function extractStatuses(description: any): string[] { + const statuses: string[] = []; + Object.values(description.clusterCollector).forEach((item: any) => { + if (item.status) statuses.push(item.status); + }); + Object.values(description.nodeCollector).forEach((item: any) => { + if (item.status) statuses.push(item.status); + }); + return statuses; +} + +// Render the description with status-specific styling +function formatOdigosDescription(description: any, refetch: () => void) { + return ( +
+ {/* Display Odigos Version with Refresh Button */} + {description.odigosVersion && ( + + + {description.odigosVersion.name}: {description.odigosVersion.value} + + + + + + )} + + {/* Display Destinations and Sources Count */} +

Destinations: {description.numberOfDestinations}

+

Sources: {description.numberOfSources}

+ + {/* Display Cluster Collector */} + + + {/* Display Node Collector */} + +
+ ); +} + +// Component to handle collector data (cluster and node collectors) +const CollectorSection: React.FC<{ title: string; collector: any }> = ({ + title, + collector, +}) => ( +
+ {title} + {Object.entries(collector).map(([key, value]: [string, any]) => ( + + ))} +
+); + +// Component to handle individual collector items with conditional styling based on status +const CollectorItem: React.FC<{ + label: string; + value: any; + status?: string; + explain?: string; +}> = ({ label, value, status, explain }) => { + const [showExplanation, setShowExplanation] = useState(false); + const color = status === 'error' ? theme.colors.error : theme.text.light_grey; + + return ( +
+ setShowExplanation(!showExplanation)} + > + - {label}: {String(value)} + + {showExplanation && {explain}} +
+ ); +}; + +const VersionHeader = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 10px; +`; + +const VersionText = styled(KeyvalText)` + font-size: 24px; +`; + +const CollectorTitle = styled(KeyvalText)` + font-size: 20px; + margin-bottom: 10px; +`; + +const NotificationBadge = styled.div<{ status: string }>` + position: absolute; + top: -4px; + right: -4px; + background-color: ${({ status }) => + status === 'error' + ? theme.colors.error + : status === 'transitioning' + ? theme.colors.orange_brown + : theme.colors.success}; + color: white; + border-radius: 50%; + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; +`; + +const IconWrapper = styled.div` + position: relative; + padding: 8px; + width: 16px; + border-radius: 8px; + border: 1px solid ${theme.colors.blue_grey}; + display: flex; + align-items: center; + cursor: pointer; + &:hover { + background-color: ${theme.colors.dark}; + } +`; + +const LoadingMessage = styled.p` + font-size: 1rem; + color: #555; +`; + +const DescriptionContent = styled(KeyvalText)` + white-space: pre-wrap; + line-height: 1.6; + padding: 20px; + max-width: 650px; +`; + +const StatusText = styled.div<{ color: string }>` + color: ${({ color }) => color}; + font-weight: bold; + cursor: pointer; +`; + +const StatusBadge = styled.span` + font-size: 0.8rem; + font-weight: normal; + margin-left: 4px; + color: inherit; +`; diff --git a/frontend/webapp/containers/main/sources/edit.source/index.tsx b/frontend/webapp/containers/main/sources/edit.source/index.tsx index d76dbea46..bd1b7eb0f 100644 --- a/frontend/webapp/containers/main/sources/edit.source/index.tsx +++ b/frontend/webapp/containers/main/sources/edit.source/index.tsx @@ -30,6 +30,8 @@ import { Conditions, } from '@/design.system'; import { BackIcon } from '@keyval-dev/design-system'; +import { SourceDescriptionDrawer } from '../source-describe'; +import styled from 'styled-components'; const NAME = 'name'; const KIND = 'kind'; @@ -106,6 +108,13 @@ export function EditSourceForm() { {SETUP.BACK} + + + {currentSource && }
@@ -146,3 +155,9 @@ export function EditSourceForm() { ); } + +const DrawerContainer = styled.div` + position: absolute; + right: 32px; + top: 16px; +`; diff --git a/frontend/webapp/containers/main/sources/source-describe/index.tsx b/frontend/webapp/containers/main/sources/source-describe/index.tsx new file mode 100644 index 000000000..580bc30d3 --- /dev/null +++ b/frontend/webapp/containers/main/sources/source-describe/index.tsx @@ -0,0 +1,282 @@ +'use client'; +import React, { useEffect, useState } from 'react'; +import { Describe, Refresh } from '@/assets'; +import theme from '@/styles/palette'; +import { useDescribe } from '@/hooks'; +import styled from 'styled-components'; +import { Drawer, KeyvalText } from '@/design.system'; + +interface SourceDescriptionDrawerProps { + namespace: string; + kind: string; + name: string; +} + +interface DescribeItem { + name: string; + value: string; + explain?: string; +} + +export const SourceDescriptionDrawer: React.FC< + SourceDescriptionDrawerProps +> = ({ namespace, kind, name }) => { + const [isOpen, setDrawerOpen] = useState(false); + const [showExplanation, setShowExplanation] = useState<{ + [key: string]: boolean; + }>({}); + const [badgeStatus, setBadgeStatus] = useState< + 'error' | 'transitioning' | 'success' + >('success'); + + const toggleDrawer = () => setDrawerOpen(!isOpen); + + const { + sourceDescription, + isSourceLoading, + fetchSourceDescription, + setNamespaceKindName, + } = useDescribe(); + + useEffect(() => { + isOpen && + namespace && + kind && + name && + setNamespaceKindName(namespace, kind, name); + }, [isOpen, namespace, kind, name]); + + useEffect(() => { + if (sourceDescription) { + const statuses = extractSourceStatuses(sourceDescription); + if (statuses.includes('error')) setBadgeStatus('error'); + else if (statuses.includes('transitioning')) + setBadgeStatus('transitioning'); + else setBadgeStatus('success'); + } + }, [sourceDescription]); + + const handleToggleExplanation = (key: string) => { + setShowExplanation((prev) => ({ + ...prev, + [key]: !prev[key], + })); + }; + + return ( + <> + + + {!isSourceLoading && ( + + + {badgeStatus === 'transitioning' + ? '...' + : badgeStatus === 'error' + ? '!' + : ''} + + + )} + + + {isOpen && ( + setDrawerOpen(false)} + position="right" + width="fit-content" + > + {isSourceLoading ? ( + Loading source details... + ) : ( + + {sourceDescription + ? formatDescription( + sourceDescription, + fetchSourceDescription, + handleToggleExplanation, + showExplanation + ) + : 'No source details available.'} + + )} + + )} + + ); +}; + +function extractSourceStatuses(description: any): string[] { + const statuses: string[] = []; + if (description.instrumentationConfig?.status) { + statuses.push(description.instrumentationConfig.status); + } + description.pods?.forEach((pod: any) => { + if (pod.phase.status) statuses.push(pod.phase.status); + }); + return statuses; +} + +// Generic function to format any description data +function formatDescription( + description: any, + refetch: () => void, + handleToggleExplanation: (key: string) => void, + showExplanation: { [key: string]: boolean } +) { + const renderObjectProperties = (obj: any, parentKey = '') => { + return Object.entries(obj).map(([key, item]: [string, DescribeItem]) => { + const uniqueKey = `${parentKey}.${key}.${JSON.stringify(item)}`; + + if ( + typeof item === 'object' && + item !== null && + item.hasOwnProperty('value') && + item.hasOwnProperty('name') + ) { + return ( +
+

handleToggleExplanation(uniqueKey)} + style={{ cursor: 'pointer' }} + > + {item.name}: {String(item.value)} +

+ {showExplanation[uniqueKey] && item.explain && ( + {item.explain} + )} +
+ ); + } else if (typeof item === 'object' && item !== null) { + return ( +
+ {renderObjectProperties(item)} +
+ ); + } else if (Array.isArray(item)) { + return ; + } + return null; + }); + }; + + return ( +
+ + {description.name?.value || 'Unnamed'} + + + + + {renderObjectProperties(description)} +
+ ); +} +// Component to handle pod data display +const CollectorSection: React.FC<{ title: string; collector: any[] }> = ({ + title, + collector, +}) => ( +
+ {title} + {collector.map((item: any, index: number) => ( + + ))} +
+); + +// Component to handle individual pod items with conditional styling based on status +const CollectorItem: React.FC<{ + label: string; + value: any; + status?: string; +}> = ({ label, value, status }) => { + const color = status === 'error' ? theme.colors.error : theme.text.light_grey; + + return ( + + - {label}: {String(value)} + + ); +}; + +const VersionHeader = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 10px; +`; + +const VersionText = styled(KeyvalText)` + font-size: 24px; +`; + +const CollectorTitle = styled(KeyvalText)` + font-size: 20px; + margin-bottom: 10px; +`; + +const NotificationBadge = styled.div<{ status: string }>` + position: absolute; + top: -4px; + right: -4px; + background-color: ${({ status }) => + status === 'error' + ? theme.colors.error + : status === 'transitioning' + ? theme.colors.orange_brown + : theme.colors.success}; + color: white; + border-radius: 50%; + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; +`; + +const IconWrapper = styled.div` + position: relative; + padding: 8px; + width: 16px; + border-radius: 8px; + border: 1px solid ${theme.colors.blue_grey}; + display: flex; + align-items: center; + cursor: pointer; + &:hover { + background-color: ${theme.colors.dark}; + } +`; + +const LoadingMessage = styled.p` + font-size: 1rem; + color: #555; +`; + +const DescriptionContent = styled(KeyvalText)` + white-space: pre-wrap; + line-height: 1.6; + padding: 20px; +`; + +const StatusText = styled.div<{ color: string }>` + color: ${({ color }) => color}; + font-weight: bold; + margin-bottom: 8px; + padding-left: 16px; +`; + +const ExplanationText = styled.p` + font-size: 0.9rem; + color: ${theme.text.light_grey}; + margin-top: -5px; + margin-bottom: 10px; +`; diff --git a/frontend/webapp/hooks/describe/index.ts b/frontend/webapp/hooks/describe/index.ts new file mode 100644 index 000000000..34deb4135 --- /dev/null +++ b/frontend/webapp/hooks/describe/index.ts @@ -0,0 +1 @@ +export * from './useDescribe'; diff --git a/frontend/webapp/hooks/describe/useDescribe.ts b/frontend/webapp/hooks/describe/useDescribe.ts new file mode 100644 index 000000000..625982cbe --- /dev/null +++ b/frontend/webapp/hooks/describe/useDescribe.ts @@ -0,0 +1,70 @@ +import { useEffect, useState } from 'react'; +import { useQuery } from 'react-query'; +import { getOdigosDescription, getSourceDescription } from '@/services'; + +export function useDescribe() { + const [namespace, setNamespace] = useState(''); + const [kind, setKind] = useState(''); + const [name, setName] = useState(''); + + // Fetch Odigos description + const { + data: odigosDescription, + isLoading: isOdigosLoading, + refetch: refetchOdigosDescription, + } = useQuery(['odigosDescription'], getOdigosDescription, { + enabled: false, + }); + + // Fetch source description based on namespace, kind, and name + const { + data: sourceDescription, + isLoading: isSourceLoading, + refetch: refetchSourceDescription, + } = useQuery( + ['sourceDescription'], + () => getSourceDescription(namespace, kind.toLowerCase(), name), + + { + onError: (error) => { + console.log(error); + }, + enabled: false, + } + ); + + useEffect(() => { + if (namespace && kind && name) { + refetchSourceDescription(); + } + }, [namespace, kind, name]); + + useEffect(() => { + console.log({ sourceDescription }); + }, [sourceDescription]); + + // Function to set parameters for source description and refetch + function fetchSourceDescription() { + refetchSourceDescription(); + } + + function setNamespaceKindName( + newNamespace: string, + newKind: string, + newName: string + ) { + setNamespace(newNamespace); + setKind(newKind); + setName(newName); + } + + return { + odigosDescription, + sourceDescription, + isOdigosLoading, + isSourceLoading, + refetchOdigosDescription, + fetchSourceDescription, + setNamespaceKindName, + }; +} diff --git a/frontend/webapp/hooks/index.tsx b/frontend/webapp/hooks/index.tsx index 5a9bee729..9528788b7 100644 --- a/frontend/webapp/hooks/index.tsx +++ b/frontend/webapp/hooks/index.tsx @@ -9,3 +9,4 @@ export * from './useNotify'; export * from './useSSE'; export * from './useOverviewMetrics'; export * from './instrumentation-rules'; +export * from './describe'; diff --git a/frontend/webapp/services/api.ts b/frontend/webapp/services/api.ts index e02ed4921..915fb68c0 100644 --- a/frontend/webapp/services/api.ts +++ b/frontend/webapp/services/api.ts @@ -1,10 +1,19 @@ import axios from 'axios'; -export async function get(url: string) { - const { data, status } = await axios.get(url); - if (status === 200) { - return data; +export async function get(url: string, headers: Record = {}) { + const response = await fetch(url, { + method: 'GET', + headers: { + ...headers, + Accept: 'application/json', + }, + }); + + if (!response.ok) { + throw new Error(`Failed to fetch data from ${url}`); } + + return response.json(); } export async function post(url: string, body: any) { diff --git a/frontend/webapp/services/describe.ts b/frontend/webapp/services/describe.ts new file mode 100644 index 000000000..2a2975bde --- /dev/null +++ b/frontend/webapp/services/describe.ts @@ -0,0 +1,16 @@ +import { get } from './api'; +import { API } from '@/utils'; + +// Function to get Odigos description +export async function getOdigosDescription(): Promise { + return get(API.DESCRIBE_ODIGOS); +} + +// Function to get source description based on namespace, kind, and name +export async function getSourceDescription( + namespace: string, + kind: string, + name: string +): Promise { + return get(API.DESCRIBE_SOURCE(namespace, kind, name)); +} diff --git a/frontend/webapp/services/index.ts b/frontend/webapp/services/index.ts index 7ecd1a2f9..a6ef21f8b 100644 --- a/frontend/webapp/services/index.ts +++ b/frontend/webapp/services/index.ts @@ -3,3 +3,4 @@ export * from './sources'; export * from './config'; export * from './actions'; export * from './instrumentation-rules'; +export * from './describe'; diff --git a/frontend/webapp/utils/constants/urls.tsx b/frontend/webapp/utils/constants/urls.tsx index 9fddce502..42ebd6e9e 100644 --- a/frontend/webapp/utils/constants/urls.tsx +++ b/frontend/webapp/utils/constants/urls.tsx @@ -22,6 +22,9 @@ const API = { INSTRUMENTATION_RULES: `${BASE_URL}/instrumentation-rules`, INSTRUMENTATION_RULE: (id: string) => `${BASE_URL}/instrumentation-rules/${id}`, + DESCRIBE_ODIGOS: `${BASE_URL}/describe/odigos`, + DESCRIBE_SOURCE: (namespace: string, kind: string, name: string) => + `${BASE_URL}/describe/source/namespace/${namespace}/kind/${kind}/name/${name}`, }; const QUERIES = { diff --git a/tests/e2e/cli-upgrade/assert-instrumented-and-pipeline.yaml b/tests/e2e/cli-upgrade/assert-instrumented-and-pipeline.yaml index eb08db461..e83ab4ced 100644 --- a/tests/e2e/cli-upgrade/assert-instrumented-and-pipeline.yaml +++ b/tests/e2e/cli-upgrade/assert-instrumented-and-pipeline.yaml @@ -22,7 +22,7 @@ apiVersion: apps/v1 kind: Deployment metadata: labels: - odigos.io/collector-role: "CLUSTER_GATEWAY" + odigos.io/collector-role: 'CLUSTER_GATEWAY' name: odigos-gateway namespace: odigos-test-cli-upgrade ownerReferences: @@ -35,11 +35,11 @@ spec: replicas: 1 selector: matchLabels: - odigos.io/collector-role: "CLUSTER_GATEWAY" + odigos.io/collector-role: 'CLUSTER_GATEWAY' template: metadata: labels: - odigos.io/collector-role: "CLUSTER_GATEWAY" + odigos.io/collector-role: 'CLUSTER_GATEWAY' spec: containers: - env: @@ -105,7 +105,7 @@ apiVersion: apps/v1 kind: DaemonSet metadata: labels: - odigos.io/collector-role: "NODE_COLLECTOR" + odigos.io/collector-role: 'NODE_COLLECTOR' name: odigos-data-collection namespace: odigos-test-cli-upgrade ownerReferences: @@ -117,11 +117,11 @@ metadata: spec: selector: matchLabels: - odigos.io/collector-role: "NODE_COLLECTOR" + odigos.io/collector-role: 'NODE_COLLECTOR' template: metadata: labels: - odigos.io/collector-role: "NODE_COLLECTOR" + odigos.io/collector-role: 'NODE_COLLECTOR' spec: containers: - name: data-collection @@ -166,15 +166,15 @@ spec: name: conf - hostPath: path: /var/log - type: "" + type: '' name: varlog - hostPath: path: /var/lib/docker/containers - type: "" + type: '' name: varlibdockercontainers - hostPath: path: /var/lib/kubelet/pod-resources - type: "" + type: '' name: kubeletpodresources status: numberAvailable: 1 @@ -191,9 +191,9 @@ spec: - name: frontend resources: limits: - instrumentation.odigos.io/java-native-community: "1" + instrumentation.odigos.io/java-native-community: '1' requests: - instrumentation.odigos.io/java-native-community: "1" + instrumentation.odigos.io/java-native-community: '1' status: containerStatuses: - name: frontend @@ -213,9 +213,9 @@ spec: - name: coupon resources: limits: - instrumentation.odigos.io/javascript-native-community: "1" + instrumentation.odigos.io/javascript-native-community: '1' requests: - instrumentation.odigos.io/javascript-native-community: "1" + instrumentation.odigos.io/javascript-native-community: '1' status: containerStatuses: - name: coupon @@ -235,9 +235,9 @@ spec: - name: inventory resources: limits: - instrumentation.odigos.io/python-native-community: "1" + instrumentation.odigos.io/python-native-community: '1' requests: - instrumentation.odigos.io/python-native-community: "1" + instrumentation.odigos.io/python-native-community: '1' status: containerStatuses: - name: inventory @@ -257,9 +257,9 @@ spec: - name: membership resources: limits: - instrumentation.odigos.io/go-ebpf-community: "1" + instrumentation.odigos.io/go-ebpf-community: '1' requests: - instrumentation.odigos.io/go-ebpf-community: "1" + instrumentation.odigos.io/go-ebpf-community: '1' status: containerStatuses: - name: membership @@ -279,9 +279,9 @@ spec: - name: pricing resources: limits: - instrumentation.odigos.io/dotnet-native-community: "1" + instrumentation.odigos.io/dotnet-native-community: '1' requests: - instrumentation.odigos.io/dotnet-native-community: "1" + instrumentation.odigos.io/dotnet-native-community: '1' status: containerStatuses: - name: pricing @@ -314,8 +314,7 @@ status: - key: k8s.container.name (value != null): true - key: k8s.pod.name - (value != null): true ---- + (value != null): true apiVersion: odigos.io/v1alpha1 kind: InstrumentationInstance metadata: @@ -337,7 +336,6 @@ status: (value != null): true - key: k8s.pod.name (value != null): true ---- apiVersion: odigos.io/v1alpha1 kind: InstrumentationInstance metadata: