blackstork-io / fabric

An open-source command-line tool for cybersecurity reporting automation and a configuration language for reusable templates. Reporting-as-Code
https://blackstork.io/fabric/
Apache License 2.0
12 stars 0 forks source link

OpenTelemetry & Parser/Eval refactoring #184

Closed dobarx closed 1 month ago

dobarx commented 1 month ago

Improvements

OpenTelemetry support

image

Exporting telemetry

Global --debug flag

Added global CLI --debug flag to save logs, traces and metrics to disk. This works for all commands.

   $ fabric render document.example --debug
   ...
   $ tree .fabric/
   .fabric
   └── debug
       └── 240512185714
           ├── logs.json
           ├── metrics.json
           └── traces.json

Exported files can be imported to other tools for inspection. They are in standard OpenTelemetry json format.

OpenTelemetry Protocol

When using fabric CLI, OpenTelemetry protocol can be enabled using environment variables. These are the default settings:

   FABRIC_OTELP_ENABLED=false
   FABRIC_OTELP_URL=https://otelp.blackstork.io

To test this, you can setup a local OpenTelemetry-Collector using docker-compose. You can use this repository: otel-compose. This will setup Collector, Loki, Tempo, Prometheus & Grafana. Next, configure environment variables:

   export FABRIC_OTELP_ENABLED=true
   export FABRIC_OTELP_URL=http://localhost:4318

Now all logs, traces & metrics are visible on Grafana:

   http://localhost:3000/explore

Example of logql query for Loki:

   {job="fabric"} | json

Using as Go library

If fabric is used as Go library, then a separate logger & tracer can be provided to configure telemetry exports. It can be sent to the collector or even stored somewhere on the database and shown to the user in the web dashboard. This does not use global state and won't trigger other loggers & tracers. Defaults are noop-Logger & noop-Tracer.

import "github.com/blackstork-io/fabric/engine"
...
eng := engine.New(
   engine.WithLogger(logger),
   engine.WithTracer(tracer),
)
defer eng.Cleanup()
diag := eng.ParseDir(ctx, fs)
...

Secret specs

Now logger logs also plugin config & arguments. To hide secrets new property was added to dataspec named Secret. This allows to replace plugin config & args values with <secret>. Example:

&dataspec.AttrSpec{
    Name:        "password",
    Type:        cty.String,
    Constraints: constraint.RequiredNonNull,
    Secret:      true,
}

This will be logged as: password=<secret>.

We could also use this property in the future to minimize risk of people leaving their secrets in .hcl files. There are two options:

Parser/Eval refactoring

To improve logging & add tracing some refactoring was done on parser & eval logic. This also makes it easier to use fabric as Go library.

Other stuff

Future