66 "fmt"
77 "slices"
88 "strings"
9+ "sync"
910 textTemplate "text/template"
1011 "text/template/parse"
1112 "time"
3536 "{{$externalURL := .ExternalURL}}" ,
3637 "{{$value := .Value}}" ,
3738 }
38- templateDefsLen = len (strings .Join (templateDefs , "" ))
39+ templateDefsString = strings .Join (templateDefs , "" )
40+ templateDefsLen = len (templateDefsString )
3941
4042 templateFuncMap = textTemplate.FuncMap {
4143 "query" : dummyFuncMap ,
6769 "externalURL" : dummyFuncMap ,
6870 "parseDuration" : dummyFuncMap ,
6971 }
72+
73+ templatePool = sync.Pool {
74+ New : func () any {
75+ t := textTemplate .
76+ New (TemplateCheckName ).
77+ Funcs (templateFuncMap ).
78+ Option ("missingkey=zero" )
79+ return t
80+ },
81+ }
7082)
7183
7284func dummyFuncMap (q string ) string {
@@ -135,7 +147,7 @@ func (c TemplateCheck) Check(ctx context.Context, entry discovery.Entry, _ []dis
135147 },
136148 })
137149 }
138- for _ , msg := range checkForValueInLabels (label .Key . Value , label . Value .Value ) {
150+ for _ , msg := range checkForValueInLabels (label .Value .Value ) {
139151 problems = append (problems , Problem {
140152 Anchor : AnchorAfter ,
141153 Lines : diags.LineRange {
@@ -194,10 +206,10 @@ func (c TemplateCheck) Check(ctx context.Context, entry discovery.Entry, _ []dis
194206}
195207
196208func (c TemplateCheck ) checkHumanizeIsNeeded (expr parser.PromQLExpr , ann * parser.YamlKeyValue ) (problems []Problem ) {
197- if ! hasValue (ann .Key . Value , ann . Value .Value ) {
209+ if ! hasValue (ann .Value .Value ) {
198210 return problems
199211 }
200- if hasHumanize (ann .Key . Value , ann . Value .Value ) {
212+ if hasHumanize (ann .Value .Value ) {
201213 return problems
202214 }
203215 vars , aliases , ok := findTemplateVariables (ann .Key .Value , ann .Value .Value )
@@ -295,7 +307,7 @@ func maybeExpandError(err error) error {
295307func checkTemplateSyntax (ctx context.Context , name , text string , data any ) error {
296308 tmpl := promTemplate .NewTemplateExpander (
297309 ctx ,
298- strings . Join ( append ( templateDefs , text ), "" ) ,
310+ templateDefsString + text ,
299311 name ,
300312 data ,
301313 model .Time (timestamp .FromTime (time .Now ())),
@@ -316,18 +328,17 @@ func checkTemplateSyntax(ctx context.Context, name, text string, data any) error
316328 return nil
317329}
318330
319- func checkForValueInLabels (name , text string ) (msgs []string ) {
320- t , err := textTemplate .
321- New (name ).
322- Funcs (templateFuncMap ).
323- Option ("missingkey=zero" ).
324- Parse (strings .Join (append (templateDefs , text ), "" ))
331+ func checkForValueInLabels (text string ) (msgs []string ) {
332+ t := templatePool .Get ().(* textTemplate.Template )
333+ defer templatePool .Put (t )
334+
335+ tt , err := t .Parse (templateDefsString + text )
325336 if err != nil {
326337 // no need to double report errors
327338 return nil
328339 }
329- aliases := aliasesForTemplate (t )
330- for _ , node := range t .Root .Nodes {
340+ aliases := aliasesForTemplate (tt )
341+ for _ , node := range tt .Root .Nodes {
331342 if v , ok := containsAliasedNode (aliases , node , ".Value" ); ok {
332343 msg := fmt .Sprintf ("Using `%s` in labels will generate a new alert on every value change, move it to annotations." , v )
333344 msgs = append (msgs , msg )
@@ -348,17 +359,16 @@ func containsAliasedNode(am aliasMap, node parse.Node, alias string) (string, bo
348359 return "" , false
349360}
350361
351- func hasValue (name , text string ) bool {
352- t , err := textTemplate .
353- New (name ).
354- Funcs (templateFuncMap ).
355- Option ("missingkey=zero" ).
356- Parse (strings .Join (append (templateDefs , text ), "" ))
362+ func hasValue (text string ) bool {
363+ t := templatePool .Get ().(* textTemplate.Template )
364+ defer templatePool .Put (t )
365+
366+ tt , err := t .Parse (templateDefsString + text )
357367 if err != nil {
358368 // no need to double report errors
359369 return false
360370 }
361- aliases := aliasesForTemplate (t )
371+ aliases := aliasesForTemplate (tt )
362372 for _ , node := range t .Root .Nodes {
363373 if _ , ok := containsAliasedNode (aliases , node , ".Value" ); ok {
364374 return true
@@ -367,19 +377,18 @@ func hasValue(name, text string) bool {
367377 return false
368378}
369379
370- func hasHumanize (name , text string ) bool {
371- t , err := textTemplate .
372- New (name ).
373- Funcs (templateFuncMap ).
374- Option ("missingkey=zero" ).
375- Parse (strings .Join (append (templateDefs , text ), "" ))
380+ func hasHumanize (text string ) bool {
381+ t := templatePool .Get ().(* textTemplate.Template )
382+ defer templatePool .Put (t )
383+
384+ tt , err := t .Parse (templateDefsString + text )
376385 if err != nil {
377386 // no need to double report errors
378387 return false
379388 }
380- aliases := aliasesForTemplate (t )
389+ aliases := aliasesForTemplate (tt )
381390
382- for _ , node := range t .Root .Nodes {
391+ for _ , node := range tt .Root .Nodes {
383392 if _ , ok := containsAliasedNode (aliases , node , ".Value" ); ! ok {
384393 continue
385394 }
@@ -474,19 +483,18 @@ func getVariables(node parse.Node) (vars []tmplVar) {
474483 return vars
475484}
476485
477- func findTemplateVariables (name , text string ) (vars []tmplVar , aliases aliasMap , ok bool ) {
478- t , err := textTemplate .
479- New (name ).
480- Funcs (templateFuncMap ).
481- Option ("missingkey=zero" ).
482- Parse (strings .Join (append (templateDefs , text ), "" ))
486+ func findTemplateVariables (_ , text string ) (vars []tmplVar , aliases aliasMap , ok bool ) {
487+ t := templatePool .Get ().(* textTemplate.Template )
488+ defer templatePool .Put (t )
489+
490+ tt , err := t .Parse (templateDefsString + text )
483491 if err != nil {
484492 // no need to double report errors
485493 return vars , aliases , false
486494 }
487495
488496 aliases .aliases = map [string ]map [string ]struct {}{}
489- for _ , node := range t .Root .Nodes {
497+ for _ , node := range tt .Root .Nodes {
490498 getAliases (node , & aliases )
491499 vars = append (vars , getVariables (node )... )
492500 }
0 commit comments