diff --git a/loki/loki-quickstart/step2.md b/loki/loki-quickstart/step2.md index 51d69b1..43e2fb0 100644 --- a/loki/loki-quickstart/step2.md +++ b/loki/loki-quickstart/step2.md @@ -39,10 +39,10 @@ You can view your logs using the command line interface, [LogCLI](https://grafan After copying any of these queries into the query editor, click **Run Query** (4) to execute the query. - 1. View all the log lines which have the container label `evaluate-loki-flog-1`{{copy}}: + 1. View all the log lines which have the container label `evaluate-loki_flog_1`{{copy}}: ```bash - {container="evaluate-loki-flog-1"} + {container="evaluate-loki_flog_1"} ```{{copy}} In Loki, this is a log stream. @@ -50,30 +50,30 @@ You can view your logs using the command line interface, [LogCLI](https://grafan Loki uses [labels](https://grafana.com/docs/loki/latest/get-started/labels/) as metadata to describe log streams. Loki queries always start with a label selector. - In the previous query, the label selector is `{container="evaluate-loki-flog-1"}`{{copy}}. + In the previous query, the label selector is `{container="evaluate-loki_flog_1"}`{{copy}}. - 1. To view all the log lines which have the container label `evaluate-loki-grafana-1`{{copy}}: + 1. To view all the log lines which have the container label `evaluate-loki_grafana_1`{{copy}}: ```bash - {container="evaluate-loki-grafana-1"} + {container="evaluate-loki_grafana_1"} ```{{copy}} - 1. Find all the log lines in the `{container="evaluate-loki-flog-1}`{{copy}} stream that contain the string `status`{{copy}}: + 1. Find all the log lines in the `{container="evaluate-loki_flog_1}`{{copy}} stream that contain the string `status`{{copy}}: ```bash - {container="evaluate-loki-flog-1"} |= `status` + {container="evaluate-loki_flog_1"} |= `status` ```{{copy}} - 1. Find all the log lines in the `{container="evaluate-loki-flog-1}`{{copy}} stream where the JSON field `status`{{copy}} has the value `404`{{copy}}: + 1. Find all the log lines in the `{container="evaluate-loki_flog_1}`{{copy}} stream where the JSON field `status`{{copy}} has the value `404`{{copy}}: ```bash - {container="evaluate-loki-flog-1"} | json | status=`404` + {container="evaluate-loki_flog_1"} | json | status=`404` ```{{copy}} 1. Calculate the number of logs per second where the JSON field `status`{{copy}} has the value `404`{{copy}}: ```bash - sum by(container) (rate({container="evaluate-loki-flog-1"} | json | status=`404` [$__auto])) + sum by(container) (rate({container="evaluate-loki_flog_1"} | json | status=`404` [$__auto])) ```{{copy}} The final query is a metric query which returns a time series. @@ -101,7 +101,7 @@ Here are some more sample queries that you can run using the Flog sample data. To see all the log lines that flog has generated, enter the LogQL query: ```bash -{container="evaluate-loki-flog-1"} +{container="evaluate-loki_flog_1"} ```{{copy}} The flog app generates log lines for simulated HTTP requests. @@ -109,25 +109,25 @@ The flog app generates log lines for simulated HTTP requests. To see all `GET`{{copy}} log lines, enter the LogQL query: ```bash -{container="evaluate-loki-flog-1"} |= "GET" +{container="evaluate-loki_flog_1"} |= "GET" ```{{copy}} To see all `POST`{{copy}} methods, enter the LogQL query: ```bash -{container="evaluate-loki-flog-1"} |= "POST" +{container="evaluate-loki_flog_1"} |= "POST" ```{{copy}} To see every log line with a 401 status (unauthorized error), enter the LogQL query: ```bash -{container="evaluate-loki-flog-1"} | json | status="401" +{container="evaluate-loki_flog_1"} | json | status="401" ```{{copy}} To see every log line that doesn’t contain the text `401`{{copy}}: ```bash -{container="evaluate-loki-flog-1"} != "401" +{container="evaluate-loki_flog_1"} != "401" ```{{copy}} For more examples, refer to the [query documentation](https://grafana.com/docs/loki/latest/query/query_examples/). diff --git a/tools/transformer/goldmark/renderer/markdown/markdown.go b/tools/transformer/goldmark/renderer/markdown/markdown.go index 5ab2a10..c5e9bd8 100644 --- a/tools/transformer/goldmark/renderer/markdown/markdown.go +++ b/tools/transformer/goldmark/renderer/markdown/markdown.go @@ -106,7 +106,6 @@ func (c *Config) SetOption(name renderer.OptionName, value interface{}) { switch name { case optKillercodaActions: c.KillercodaActions = value.(bool) - } } diff --git a/tools/transformer/main.go b/tools/transformer/main.go index 567291f..e251abf 100644 --- a/tools/transformer/main.go +++ b/tools/transformer/main.go @@ -39,20 +39,12 @@ func usage(w io.Writer, fs *flag.FlagSet) { fmt.Fprintln(w, " Path to the Killercoda output directory") } -func writeIntro(dstDirPath string, data []byte, renderer renderer.Renderer) error { +func writeIntro(dstDirPath string, data []byte, transformers []util.PrioritizedValue, renderer renderer.Renderer) error { md := goldmark.NewMarkdown() - //nolint:gomnd // These priority values are relative to each other and are not magic. - md.Parser().AddOptions(parser.WithASTTransformers( - util.Prioritized(&IntroTransformer{}, 0), - util.Prioritized(&IgnoreTransformer{}, 1), - util.Prioritized(&IncludeTransformer{}, 1), - util.Prioritized(&FigureTransformer{}, 2), - util.Prioritized(&InlineActionTransformer{}, 3), - util.Prioritized(&ActionTransformer{Kind: "copy"}, 3), - util.Prioritized(&ActionTransformer{Kind: "exec"}, 3), - util.Prioritized(&LinkTransformer{}, 4), - util.Prioritized(&HeadingTransformer{}, 5), - )) + md.Parser().AddOptions( + parser.WithASTTransformers( + append(transformers, util.Prioritized(&IntroTransformer{}, 0))...), + ) md.SetRenderer(renderer) root := md.Parser().Parse(text.NewReader(data)) @@ -69,20 +61,12 @@ func writeIntro(dstDirPath string, data []byte, renderer renderer.Renderer) erro return nil } -func writeFinish(dstDirPath string, data []byte, renderer renderer.Renderer) error { +func writeFinish(dstDirPath string, data []byte, transformers []util.PrioritizedValue, renderer renderer.Renderer) error { md := goldmark.NewMarkdown() - //nolint:gomnd // These priority values are relative to each other and are not magic. - md.Parser().AddOptions(parser.WithASTTransformers( - util.Prioritized(&FinishTransformer{}, 0), - util.Prioritized(&IgnoreTransformer{}, 1), - util.Prioritized(&IncludeTransformer{}, 1), - util.Prioritized(&FigureTransformer{}, 2), - util.Prioritized(&InlineActionTransformer{}, 3), - util.Prioritized(&ActionTransformer{Kind: "copy"}, 3), - util.Prioritized(&ActionTransformer{Kind: "exec"}, 3), - util.Prioritized(&LinkTransformer{}, 4), - util.Prioritized(&HeadingTransformer{}, 5), - )) + md.Parser().AddOptions( + parser.WithASTTransformers( + append(transformers, util.Prioritized(&FinishTransformer{}, 0))...), + ) md.SetRenderer(renderer) root := md.Parser().Parse(text.NewReader(data)) @@ -99,20 +83,12 @@ func writeFinish(dstDirPath string, data []byte, renderer renderer.Renderer) err return nil } -func writeStep(dstDirPath string, n int, data []byte, renderer renderer.Renderer) error { +func writeStep(dstDirPath string, n int, data []byte, transformers []util.PrioritizedValue, renderer renderer.Renderer) error { md := goldmark.NewMarkdown() - //nolint:gomnd // These priority values are relative to each other and are not magic. - md.Parser().AddOptions(parser.WithASTTransformers( - util.Prioritized(&StepTransformer{Step: n}, 0), - util.Prioritized(&IgnoreTransformer{}, 1), - util.Prioritized(&IncludeTransformer{}, 1), - util.Prioritized(&FigureTransformer{}, 2), - util.Prioritized(&InlineActionTransformer{}, 3), - util.Prioritized(&ActionTransformer{Kind: "copy"}, 3), - util.Prioritized(&ActionTransformer{Kind: "exec"}, 3), - util.Prioritized(&LinkTransformer{}, 4), - util.Prioritized(&HeadingTransformer{}, 5), - )) + md.Parser().AddOptions( + parser.WithASTTransformers( + append(transformers, util.Prioritized(&StepTransformer{Step: n}, 0))...), + ) md.SetRenderer(renderer) root := md.Parser().Parse(text.NewReader(data)) @@ -129,15 +105,7 @@ func writeStep(dstDirPath string, n int, data []byte, renderer renderer.Renderer return nil } -func writeIndex(dstDirPath string, data []byte, steps int, wroteIntro bool, wroteFinish bool) error { - md := goldmark.NewMarkdown() - root := md.Parser().Parse(text.NewReader(data)) - - meta, ok := root.OwnerDocument().Meta()["killercoda"].(map[any]any) - if !ok { - return fmt.Errorf("couldn't find metadata in source file front matter") - } - +func writeIndex(dstDirPath string, meta map[any]any, steps int, wroteIntro bool, wroteFinish bool) error { index, err := killercoda.FromMeta(meta) if err != nil { return fmt.Errorf("couldn't parse metadata: %w", err) @@ -179,6 +147,39 @@ func transform(srcFilePath, dstDirPath string) error { return fmt.Errorf("couldn't open source file: %w", err) } + md := goldmark.NewMarkdown() + root := md.Parser().Parse(text.NewReader(data)) + + meta, ok := root.OwnerDocument().Meta()["killercoda"].(map[any]any) + if !ok { + return fmt.Errorf("couldn't find metadata in source file front matter") + } + + if preprocessing, ok := meta["preprocessing"].(map[any]any); ok { + if substitutions, ok := preprocessing["substitutions"].([]any); ok { + for _, substitution := range substitutions { + if s, ok := substitution.(map[any]any); ok { + if expr, ok := s["regexp"].(string); ok { + if replacement, ok := s["replacement"].(string); ok { + data = regexp.MustCompile(expr).ReplaceAll(data, []byte(replacement)) + } + } + } + } + } + } + + transformers := []util.PrioritizedValue{ + util.Prioritized(&IgnoreTransformer{}, 1), + util.Prioritized(&IncludeTransformer{}, 1), + util.Prioritized(&FigureTransformer{}, 2), + util.Prioritized(&InlineActionTransformer{}, 3), + util.Prioritized(&ActionTransformer{Kind: "copy"}, 3), + util.Prioritized(&ActionTransformer{Kind: "exec"}, 3), + util.Prioritized(&LinkTransformer{}, 4), + util.Prioritized(&HeadingTransformer{}, 5), + } + //nolint:gomnd // These priority values are relative to each other and are not magic. renderer := renderer.NewRenderer( renderer.WithNodeRenderers( @@ -193,7 +194,7 @@ func transform(srcFilePath, dstDirPath string) error { ) if bytes.Contains(data, []byte(introStartMarker)) { - if err := writeIntro(dstDirPath, data, renderer); err != nil { + if err := writeIntro(dstDirPath, data, transformers, renderer); err != nil { return err } @@ -201,7 +202,7 @@ func transform(srcFilePath, dstDirPath string) error { } if bytes.Contains(data, []byte(finishStartMarker)) { - if err := writeFinish(dstDirPath, data, renderer); err != nil { + if err := writeFinish(dstDirPath, data, transformers, renderer); err != nil { return err } @@ -217,13 +218,13 @@ func transform(srcFilePath, dstDirPath string) error { if regexp.MustCompile(fmt.Sprintf(``, i)).Match(data) { steps++ - if err := writeStep(dstDirPath, i, data, renderer); err != nil { + if err := writeStep(dstDirPath, i, data, transformers, renderer); err != nil { errs = errors.Join(errs, err) } } } - writeIndex(dstDirPath, data, steps, wroteIntro, wroteFinish) + writeIndex(dstDirPath, meta, steps, wroteIntro, wroteFinish) return errs }