diff --git a/.betterer.results b/.betterer.results
index e861dbe1415..4018a113db2 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -3276,8 +3276,7 @@ exports[`better eslint`] = {
       [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
     ],
     "public/app/features/explore/Logs/LogsMetaRow.tsx:5381": [
-      [0, 0, 0, "Styles should be written using objects.", "0"],
-      [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
+      [0, 0, 0, "Styles should be written using objects.", "0"]
     ],
     "public/app/features/explore/Logs/LogsNavigation.tsx:5381": [
       [0, 0, 0, "Styles should be written using objects.", "0"],
@@ -6019,9 +6018,6 @@ exports[`better eslint`] = {
       [0, 0, 0, "Styles should be written using objects.", "6"],
       [0, 0, 0, "Styles should be written using objects.", "7"]
     ],
-    "public/app/plugins/panel/logs/LogsPanel.tsx:5381": [
-      [0, 0, 0, "Do not use any type assertions.", "0"]
-    ],
     "public/app/plugins/panel/logs/types.ts:5381": [
       [0, 0, 0, "Do not re-export imported variable (\`./panelcfg.gen\`)", "0"]
     ],
diff --git a/public/app/features/explore/Logs/LogsMetaRow.tsx b/public/app/features/explore/Logs/LogsMetaRow.tsx
index 55f5bdacc02..b6608f69b20 100644
--- a/public/app/features/explore/Logs/LogsMetaRow.tsx
+++ b/public/app/features/explore/Logs/LogsMetaRow.tsx
@@ -13,13 +13,14 @@ import {
   transformDataFrame,
   DataTransformerConfig,
   CustomTransformOperator,
+  Labels,
 } from '@grafana/data';
 import { DataFrame } from '@grafana/data/';
 import { reportInteraction } from '@grafana/runtime';
 import { Button, Dropdown, Menu, ToolbarButton, Tooltip, useStyles2 } from '@grafana/ui';
 
 import { downloadDataFrameAsCsv, downloadLogsModelAsTxt } from '../../inspector/utils/download';
-import { LogLabels } from '../../logs/components/LogLabels';
+import { LogLabels, LogLabelsList } from '../../logs/components/LogLabels';
 import { MAX_CHARACTERS } from '../../logs/components/LogRowMessage';
 import { logRowsToReadableJson } from '../../logs/utils';
 import { MetaInfoText, MetaItemProps } from '../MetaInfoText';
@@ -133,7 +134,7 @@ export const LogsMetaRow = React.memo(
       logsMetaItem.push(
         {
           label: 'Showing only selected fields',
-          value: renderMetaItem(displayedFields, LogsMetaKind.LabelsMap),
+          value: <LogLabelsList labels={displayedFields} />,
         },
         {
           label: '',
@@ -195,11 +196,16 @@ export const LogsMetaRow = React.memo(
 
 LogsMetaRow.displayName = 'LogsMetaRow';
 
-function renderMetaItem(value: any, kind: LogsMetaKind) {
+function renderMetaItem(value: string | number | Labels, kind: LogsMetaKind) {
+  if (typeof value === 'string' || typeof value === 'number') {
+    return <>{value}</>;
+  }
   if (kind === LogsMetaKind.LabelsMap) {
     return <LogLabels labels={value} />;
-  } else if (kind === LogsMetaKind.Error) {
-    return <span className="logs-meta-item__error">{value}</span>;
   }
-  return value;
+  if (kind === LogsMetaKind.Error) {
+    return <span className="logs-meta-item__error">{value.toString()}</span>;
+  }
+  console.error(`Meta type ${typeof value} ${value} not recognized.`);
+  return <></>;
 }
diff --git a/public/app/features/logs/components/LogLabels.test.tsx b/public/app/features/logs/components/LogLabels.test.tsx
index e76459f0b65..9bfd070d9a7 100644
--- a/public/app/features/logs/components/LogLabels.test.tsx
+++ b/public/app/features/logs/components/LogLabels.test.tsx
@@ -1,27 +1,35 @@
 import { render, screen } from '@testing-library/react';
 import React from 'react';
 
-import { LogLabels } from './LogLabels';
+import { LogLabels, LogLabelsList } from './LogLabels';
 
 describe('<LogLabels />', () => {
   it('renders notice when no labels are found', () => {
-    render(<LogLabels labels={{}} />);
+    render(<LogLabels labels={{}} emptyMessage="(no unique labels)" />);
     expect(screen.queryByText('(no unique labels)')).toBeInTheDocument();
   });
   it('renders labels', () => {
     render(<LogLabels labels={{ foo: 'bar', baz: '42' }} />);
-    expect(screen.queryByText('bar')).toBeInTheDocument();
-    expect(screen.queryByText('42')).toBeInTheDocument();
+    expect(screen.queryByText('foo=bar')).toBeInTheDocument();
+    expect(screen.queryByText('baz=42')).toBeInTheDocument();
   });
   it('excludes labels with certain names or labels starting with underscore', () => {
     render(<LogLabels labels={{ foo: 'bar', level: '42', _private: '13' }} />);
-    expect(screen.queryByText('bar')).toBeInTheDocument();
-    expect(screen.queryByText('42')).not.toBeInTheDocument();
+    expect(screen.queryByText('foo=bar')).toBeInTheDocument();
+    expect(screen.queryByText('level=42')).not.toBeInTheDocument();
     expect(screen.queryByText('13')).not.toBeInTheDocument();
   });
   it('excludes labels with empty string values', () => {
     render(<LogLabels labels={{ foo: 'bar', baz: '' }} />);
-    expect(screen.queryByText('bar')).toBeInTheDocument();
-    expect(screen.queryByText('baz')).not.toBeInTheDocument();
+    expect(screen.queryByText('foo=bar')).toBeInTheDocument();
+    expect(screen.queryByText(/baz/)).not.toBeInTheDocument();
+  });
+});
+
+describe('<LogLabelsList />', () => {
+  it('renders labels', () => {
+    render(<LogLabelsList labels={['bar', '42']} />);
+    expect(screen.queryByText('bar')).toBeInTheDocument();
+    expect(screen.queryByText('42')).toBeInTheDocument();
   });
 });
diff --git a/public/app/features/logs/components/LogLabels.tsx b/public/app/features/logs/components/LogLabels.tsx
index 3f76fda46dd..2305ad7e866 100644
--- a/public/app/features/logs/components/LogLabels.tsx
+++ b/public/app/features/logs/components/LogLabels.tsx
@@ -1,47 +1,90 @@
 import { css, cx } from '@emotion/css';
-import React from 'react';
+import React, { useMemo } from 'react';
 
 import { GrafanaTheme2, Labels } from '@grafana/data';
-import { useStyles2 } from '@grafana/ui';
+import { Tooltip, useStyles2 } from '@grafana/ui';
 
 // Levels are already encoded in color, filename is a Loki-ism
 const HIDDEN_LABELS = ['level', 'lvl', 'filename'];
 
 interface Props {
   labels: Labels;
+  emptyMessage?: string;
 }
 
-export const LogLabels = ({ labels }: Props) => {
+export const LogLabels = React.memo(({ labels, emptyMessage }: Props) => {
   const styles = useStyles2(getStyles);
-  const displayLabels = Object.keys(labels).filter((label) => !label.startsWith('_') && !HIDDEN_LABELS.includes(label));
+  const displayLabels = useMemo(
+    () =>
+      Object.keys(labels)
+        .filter((label) => !label.startsWith('_') && !HIDDEN_LABELS.includes(label))
+        .sort(),
+    [labels]
+  );
 
-  if (displayLabels.length === 0) {
+  if (displayLabels.length === 0 && emptyMessage) {
     return (
       <span className={cx([styles.logsLabels])}>
-        <span className={cx([styles.logsLabel])}>(no unique labels)</span>
+        <span className={cx([styles.logsLabel])}>{emptyMessage}</span>
       </span>
     );
   }
 
   return (
     <span className={cx([styles.logsLabels])}>
-      {displayLabels.sort().map((label) => {
+      {displayLabels.map((label) => {
         const value = labels[label];
         if (!value) {
           return;
         }
-        const tooltip = `${label}: ${value}`;
+        const labelValue = `${label}=${value}`;
         return (
-          <span key={label} className={cx([styles.logsLabel])}>
-            <span className={cx([styles.logsLabelValue])} title={tooltip}>
-              {value}
-            </span>
-          </span>
+          <Tooltip content={labelValue} key={label} placement="top">
+            <LogLabel styles={styles}>{labelValue}</LogLabel>
+          </Tooltip>
         );
       })}
     </span>
   );
-};
+});
+LogLabels.displayName = 'LogLabels';
+
+interface LogLabelsArrayProps {
+  labels: string[];
+}
+
+export const LogLabelsList = React.memo(({ labels }: LogLabelsArrayProps) => {
+  const styles = useStyles2(getStyles);
+  return (
+    <span className={cx([styles.logsLabels])}>
+      {labels.map((label) => (
+        <LogLabel key={label} styles={styles} tooltip={label}>
+          {label}
+        </LogLabel>
+      ))}
+    </span>
+  );
+});
+LogLabelsList.displayName = 'LogLabelsList';
+
+interface LogLabelProps {
+  styles: Record<string, string>;
+  tooltip?: string;
+  children: JSX.Element | string;
+}
+
+const LogLabel = React.forwardRef<HTMLSpanElement, LogLabelProps>(
+  ({ styles, tooltip, children }: LogLabelProps, ref) => {
+    return (
+      <span className={cx([styles.logsLabel])} ref={ref}>
+        <span className={cx([styles.logsLabelValue])} title={tooltip}>
+          {children}
+        </span>
+      </span>
+    );
+  }
+);
+LogLabel.displayName = 'LogLabel';
 
 const getStyles = (theme: GrafanaTheme2) => {
   return {
diff --git a/public/app/plugins/panel/logs/LogsPanel.test.tsx b/public/app/plugins/panel/logs/LogsPanel.test.tsx
index 7c3fdbf0726..2230f70dae1 100644
--- a/public/app/plugins/panel/logs/LogsPanel.test.tsx
+++ b/public/app/plugins/panel/logs/LogsPanel.test.tsx
@@ -87,7 +87,7 @@ describe('LogsPanel', () => {
         options: { showCommonLabels: true, sortOrder: LogsSortOrder.Descending },
       });
       expect(await screen.findByText(/common labels:/i)).toBeInTheDocument();
-      expect(container.firstChild?.childNodes[0].textContent).toMatch(/^Common labels:common_appcommon_job/);
+      expect(container.firstChild?.childNodes[0].textContent).toMatch(/^Common labels:app=common_appjob=common_job/);
     });
     it('shows common labels on bottom when ascending sort order', async () => {
       const { container } = setup({
@@ -95,7 +95,7 @@ describe('LogsPanel', () => {
         options: { showCommonLabels: true, sortOrder: LogsSortOrder.Ascending },
       });
       expect(await screen.findByText(/common labels:/i)).toBeInTheDocument();
-      expect(container.firstChild?.childNodes[0].textContent).toMatch(/Common labels:common_appcommon_job$/);
+      expect(container.firstChild?.childNodes[0].textContent).toMatch(/Common labels:app=common_appjob=common_job$/);
     });
     it('does not show common labels when showCommonLabels is set to false', async () => {
       setup({ data: { series: seriesWithCommonLabels }, options: { showCommonLabels: false } });
diff --git a/public/app/plugins/panel/logs/LogsPanel.tsx b/public/app/plugins/panel/logs/LogsPanel.tsx
index 8069088e533..40aa8dab3f0 100644
--- a/public/app/plugins/panel/logs/LogsPanel.tsx
+++ b/public/app/plugins/panel/logs/LogsPanel.tsx
@@ -39,6 +39,8 @@ interface LogsPermalinkUrlState {
   };
 }
 
+const noCommonLabels: Labels = {};
+
 export const LogsPanel = ({
   data,
   timeZone,
@@ -225,7 +227,10 @@ export const LogsPanel = ({
   const renderCommonLabels = () => (
     <div className={cx(style.labelContainer, isAscending && style.labelContainerAscending)}>
       <span className={style.label}>Common labels:</span>
-      <LogLabels labels={commonLabels ? (commonLabels.value as Labels) : { labels: '(no common labels)' }} />
+      <LogLabels
+        labels={typeof commonLabels?.value === 'object' ? commonLabels?.value : noCommonLabels}
+        emptyMessage="(no common labels)"
+      />
     </div>
   );