@@ -54,6 +54,23 @@ export class LogDomain extends Domain {
5454 }
5555}
5656
57+ /**
58+ * Converts a string to a legal Loki label name by replacing illegal characters with underscores.
59+ * Loki label names must match the regex [a-zA-Z_:][a-zA-Z0-9_:]*
60+ * @param input - The input string to sanitize
61+ * @returns A sanitized string safe for use as a Loki label name
62+ */
63+ export const cleanLokiLabel = ( input : string ) : string => {
64+ if ( ! input ) return '_' ;
65+ // Replace any character that's not alphanumeric, underscore, or colon with underscore
66+ const sanitized = input . replace ( / [ ^ a - z A - Z 0 - 9 _ : ] / g, '_' ) ;
67+ // Ensure the first character is valid (letter, underscore, or colon)
68+ if ( ! / ^ [ a - z A - Z _ : ] / . test ( sanitized ) ) {
69+ return '_' + sanitized ;
70+ }
71+ return sanitized ;
72+ } ;
73+
5774const directToLogQL = ( maybeDirect : string ) : string | undefined => {
5875 try {
5976 // Try to parse the selector as k8s pod selector, and translate to logQL.
@@ -68,7 +85,7 @@ const directToLogQL = (maybeDirect: string): string | undefined => {
6885 const pipeline =
6986 direct ?. labels && typeof direct . labels === 'object'
7087 ? Object . entries ( direct . labels )
71- . map ( ( [ k , v ] ) => `|kubernetes_labels_${ k } ="${ v } "` )
88+ . map ( ( [ k , v ] ) => `|kubernetes_labels_${ cleanLokiLabel ( k ) } ="${ v } "` )
7289 . join ( '' )
7390 : '' ;
7491 return `{${ streams } }${ pipeline ? '|json' + pipeline : '' } ` ;
0 commit comments