mirror of https://github.com/grafana/loki
operator: Add support for reconciling loki-mixin dashboards on OpenShift Console (#9468)
Co-authored-by: Robert Jacob <xperimental@solidproject.de>pull/9692/head
parent
8ca1d1e0a4
commit
38556c1d37
@ -0,0 +1,5 @@ |
|||||||
|
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT |
||||||
|
|
||||||
|
go 1.20 |
||||||
|
|
||||||
|
require github.com/jsonnet-bundler/jsonnet-bundler v0.5.1 // cmd/jb |
@ -0,0 +1,50 @@ |
|||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= |
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= |
||||||
|
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= |
||||||
|
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= |
||||||
|
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= |
||||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= |
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||||
|
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= |
||||||
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= |
||||||
|
github.com/jsonnet-bundler/jsonnet-bundler v0.5.1 h1:eUd6EA1Qzz73Q4NLNLOrNkMb96+6NTTERbX9lqaxVwk= |
||||||
|
github.com/jsonnet-bundler/jsonnet-bundler v0.5.1/go.mod h1:Qrdw/7mOFS2SKCOALKFfEH8gdvXJi8XZjw9g5ilpf4I= |
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= |
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= |
||||||
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= |
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= |
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= |
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= |
||||||
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= |
||||||
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= |
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= |
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= |
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= |
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= |
||||||
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= |
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= |
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
||||||
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= |
||||||
|
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= |
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= |
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= |
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= |
||||||
|
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= |
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||||
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||||
|
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= |
||||||
|
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= |
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= |
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= |
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= |
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
@ -0,0 +1,5 @@ |
|||||||
|
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT |
||||||
|
|
||||||
|
go 1.20 |
||||||
|
|
||||||
|
require github.com/google/go-jsonnet v0.20.0 // cmd/jsonnet |
@ -0,0 +1,17 @@ |
|||||||
|
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= |
||||||
|
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= |
||||||
|
github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g= |
||||||
|
github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA= |
||||||
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= |
||||||
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= |
||||||
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= |
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= |
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= |
||||||
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||||
|
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= |
||||||
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
||||||
|
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= |
||||||
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= |
@ -0,0 +1,5 @@ |
|||||||
|
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT |
||||||
|
|
||||||
|
go 1.20 |
||||||
|
|
||||||
|
require github.com/google/go-jsonnet v0.20.0 // cmd/jsonnetfmt |
@ -0,0 +1,17 @@ |
|||||||
|
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= |
||||||
|
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= |
||||||
|
github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g= |
||||||
|
github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA= |
||||||
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= |
||||||
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= |
||||||
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= |
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= |
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= |
||||||
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||||
|
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= |
||||||
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
||||||
|
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= |
||||||
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= |
@ -0,0 +1,66 @@ |
|||||||
|
package controllers |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
|
||||||
|
"github.com/ViaQ/logerr/v2/kverrors" |
||||||
|
"github.com/go-logr/logr" |
||||||
|
lokiv1 "github.com/grafana/loki/operator/apis/loki/v1" |
||||||
|
"github.com/grafana/loki/operator/internal/handlers" |
||||||
|
"k8s.io/apimachinery/pkg/labels" |
||||||
|
"k8s.io/apimachinery/pkg/runtime" |
||||||
|
ctrl "sigs.k8s.io/controller-runtime" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/builder" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/event" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/manager" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/predicate" |
||||||
|
) |
||||||
|
|
||||||
|
var createOrDeletesPred = builder.WithPredicates(predicate.Funcs{ |
||||||
|
UpdateFunc: func(e event.UpdateEvent) bool { return false }, |
||||||
|
CreateFunc: func(e event.CreateEvent) bool { return true }, |
||||||
|
DeleteFunc: func(e event.DeleteEvent) bool { return true }, |
||||||
|
GenericFunc: func(e event.GenericEvent) bool { return false }, |
||||||
|
}) |
||||||
|
|
||||||
|
// DashboardsReconciler deploys and removes the cluster-global resources needed
|
||||||
|
// for the metrics dashboards depending on whether any LokiStacks exist.
|
||||||
|
type DashboardsReconciler struct { |
||||||
|
client.Client |
||||||
|
Scheme *runtime.Scheme |
||||||
|
Log logr.Logger |
||||||
|
OperatorNs string |
||||||
|
} |
||||||
|
|
||||||
|
// Reconcile creates all LokiStack dashboard ConfigMap and PrometheusRule objects on OpenShift clusters when
|
||||||
|
// the at least one LokiStack custom resource exists or removes all when none.
|
||||||
|
func (r *DashboardsReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { |
||||||
|
var stacks lokiv1.LokiStackList |
||||||
|
if err := r.List(ctx, &stacks, client.MatchingLabelsSelector{Selector: labels.Everything()}); err != nil { |
||||||
|
return ctrl.Result{}, kverrors.Wrap(err, "failed to list any lokistack instances") |
||||||
|
} |
||||||
|
|
||||||
|
if len(stacks.Items) == 0 { |
||||||
|
// Removes all LokiStack dashboard resources on OpenShift clusters when
|
||||||
|
// the last LokiStack custom resource is deleted.
|
||||||
|
if err := handlers.DeleteDashboards(ctx, r.Client, r.OperatorNs); err != nil { |
||||||
|
return ctrl.Result{}, kverrors.Wrap(err, "failed to delete dashboard resources") |
||||||
|
} |
||||||
|
return ctrl.Result{}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Creates all LokiStack dashboard resources on OpenShift clusters when
|
||||||
|
// the first LokiStack custom resource is created.
|
||||||
|
if err := handlers.CreateDashboards(ctx, r.Log, r.OperatorNs, r.Client, r.Scheme); err != nil { |
||||||
|
return ctrl.Result{}, kverrors.Wrap(err, "failed to create dashboard resources", "req", req) |
||||||
|
} |
||||||
|
return ctrl.Result{}, nil |
||||||
|
} |
||||||
|
|
||||||
|
// SetupWithManager sets up the controller with the Manager to only call this controller on create/delete/generic events.
|
||||||
|
func (r *DashboardsReconciler) SetupWithManager(mgr manager.Manager) error { |
||||||
|
return ctrl.NewControllerManagedBy(mgr). |
||||||
|
For(&lokiv1.LokiStack{}, createOrDeletesPred). |
||||||
|
Complete(r) |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
package handlers |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"github.com/ViaQ/logerr/v2/kverrors" |
||||||
|
"github.com/go-logr/logr" |
||||||
|
"github.com/grafana/loki/operator/internal/external/k8s" |
||||||
|
"github.com/grafana/loki/operator/internal/manifests" |
||||||
|
"github.com/grafana/loki/operator/internal/manifests/openshift" |
||||||
|
"k8s.io/apimachinery/pkg/runtime" |
||||||
|
ctrl "sigs.k8s.io/controller-runtime" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client" |
||||||
|
ctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" |
||||||
|
) |
||||||
|
|
||||||
|
// CreateDashboards handles the LokiStack dashboards create events.
|
||||||
|
func CreateDashboards(ctx context.Context, log logr.Logger, operatorNs string, k k8s.Client, s *runtime.Scheme) error { |
||||||
|
objs, err := openshift.BuildDashboards(operatorNs) |
||||||
|
if err != nil { |
||||||
|
return kverrors.Wrap(err, "failed to build dashboard manifests") |
||||||
|
} |
||||||
|
|
||||||
|
var errCount int32 |
||||||
|
for _, obj := range objs { |
||||||
|
desired := obj.DeepCopyObject().(client.Object) |
||||||
|
mutateFn := manifests.MutateFuncFor(obj, desired, nil) |
||||||
|
|
||||||
|
op, err := ctrl.CreateOrUpdate(ctx, k, obj, mutateFn) |
||||||
|
if err != nil { |
||||||
|
log.Error(err, "failed to configure resource") |
||||||
|
errCount++ |
||||||
|
continue |
||||||
|
} |
||||||
|
|
||||||
|
msg := fmt.Sprintf("Resource has been %s", op) |
||||||
|
switch op { |
||||||
|
case ctrlutil.OperationResultNone: |
||||||
|
log.V(1).Info(msg) |
||||||
|
default: |
||||||
|
log.Info(msg) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if errCount > 0 { |
||||||
|
return kverrors.New("failed to configure lokistack dashboard resources") |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
package handlers |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"testing" |
||||||
|
|
||||||
|
lokiv1 "github.com/grafana/loki/operator/apis/loki/v1" |
||||||
|
"github.com/grafana/loki/operator/internal/external/k8s/k8sfakes" |
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert" |
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors" |
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema" |
||||||
|
"k8s.io/apimachinery/pkg/types" |
||||||
|
ctrl "sigs.k8s.io/controller-runtime" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client" |
||||||
|
) |
||||||
|
|
||||||
|
func TestCreateDashboards_ReturnsResourcesInManagedNamespaces(t *testing.T) { |
||||||
|
sw := &k8sfakes.FakeStatusWriter{} |
||||||
|
k := &k8sfakes.FakeClient{} |
||||||
|
r := ctrl.Request{ |
||||||
|
NamespacedName: types.NamespacedName{ |
||||||
|
Name: "my-stack", |
||||||
|
Namespace: "some-ns", |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
stack := lokiv1.LokiStack{ |
||||||
|
TypeMeta: metav1.TypeMeta{ |
||||||
|
Kind: "LokiStack", |
||||||
|
}, |
||||||
|
ObjectMeta: metav1.ObjectMeta{ |
||||||
|
Name: "my-stack", |
||||||
|
Namespace: "some-ns", |
||||||
|
UID: "b23f9a38-9672-499f-8c29-15ede74d3ece", |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
k.GetStub = func(_ context.Context, name types.NamespacedName, out client.Object, _ ...client.GetOption) error { |
||||||
|
if r.Name == name.Name && r.Namespace == name.Namespace { |
||||||
|
k.SetClientObject(out, &stack) |
||||||
|
return nil |
||||||
|
} |
||||||
|
return apierrors.NewNotFound(schema.GroupResource{}, "something wasn't found") |
||||||
|
} |
||||||
|
|
||||||
|
k.CreateStub = func(_ context.Context, o client.Object, _ ...client.CreateOption) error { |
||||||
|
assert.NotEqual(t, r.Namespace, o.GetNamespace()) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
k.StatusStub = func() client.StatusWriter { return sw } |
||||||
|
|
||||||
|
err := CreateDashboards(context.TODO(), logger, "test", k, scheme) |
||||||
|
require.NoError(t, err) |
||||||
|
|
||||||
|
// make sure create was called
|
||||||
|
require.NotZero(t, k.CreateCallCount()) |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package handlers |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
|
||||||
|
"github.com/ViaQ/logerr/v2/kverrors" |
||||||
|
"github.com/grafana/loki/operator/internal/external/k8s" |
||||||
|
"github.com/grafana/loki/operator/internal/manifests/openshift" |
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client" |
||||||
|
) |
||||||
|
|
||||||
|
// DeleteDashboards removes all cluster-scoped dashboard resources.
|
||||||
|
func DeleteDashboards(ctx context.Context, k k8s.Client, operatorNs string) error { |
||||||
|
objs, err := openshift.BuildDashboards(operatorNs) |
||||||
|
if err != nil { |
||||||
|
return kverrors.Wrap(err, "failed to build dashboards manifests") |
||||||
|
} |
||||||
|
|
||||||
|
for _, obj := range objs { |
||||||
|
key := client.ObjectKeyFromObject(obj) |
||||||
|
if err := k.Delete(ctx, obj, &client.DeleteOptions{}); err != nil { |
||||||
|
if apierrors.IsNotFound(err) { |
||||||
|
continue |
||||||
|
} |
||||||
|
return kverrors.Wrap(err, "failed to delete dashboard", "key", key) |
||||||
|
} |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package handlers |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/grafana/loki/operator/internal/external/k8s/k8sfakes" |
||||||
|
"github.com/grafana/loki/operator/internal/manifests/openshift" |
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors" |
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema" |
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client" |
||||||
|
) |
||||||
|
|
||||||
|
func TestDeleteDashboards(t *testing.T) { |
||||||
|
objs, err := openshift.BuildDashboards("operator-ns") |
||||||
|
require.NoError(t, err) |
||||||
|
|
||||||
|
k := &k8sfakes.FakeClient{} |
||||||
|
|
||||||
|
err = DeleteDashboards(context.TODO(), k, "operator-ns") |
||||||
|
require.NoError(t, err) |
||||||
|
require.Equal(t, k.DeleteCallCount(), len(objs)) |
||||||
|
} |
||||||
|
|
||||||
|
func TestDeleteDashboards_ReturnsNoError_WhenNotFound(t *testing.T) { |
||||||
|
k := &k8sfakes.FakeClient{} |
||||||
|
k.DeleteStub = func(context.Context, client.Object, ...client.DeleteOption) error { |
||||||
|
return apierrors.NewNotFound(schema.GroupResource{}, "something wasn't found") |
||||||
|
} |
||||||
|
|
||||||
|
err := DeleteDashboards(context.TODO(), k, "operator-ns") |
||||||
|
require.NoError(t, err) |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
package openshift |
||||||
|
|
||||||
|
import ( |
||||||
|
"strings" |
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1" |
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client" |
||||||
|
|
||||||
|
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" |
||||||
|
|
||||||
|
"github.com/grafana/loki/operator/internal/manifests/openshift/internal/dashboards" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
labelConsoleDashboard = "console.openshift.io/dashboard" |
||||||
|
managedConfigNamespace = "openshift-config-managed" |
||||||
|
) |
||||||
|
|
||||||
|
func BuildDashboards(operatorNs string) ([]client.Object, error) { |
||||||
|
ds, rules := dashboards.Content() |
||||||
|
|
||||||
|
var objs []client.Object |
||||||
|
for name, content := range ds { |
||||||
|
objs = append(objs, newDashboardConfigMap(name, content)) |
||||||
|
} |
||||||
|
|
||||||
|
promRule, err := newDashboardPrometheusRule(operatorNs, rules) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
objs = append(objs, promRule) |
||||||
|
|
||||||
|
return objs, nil |
||||||
|
} |
||||||
|
|
||||||
|
func newDashboardConfigMap(filename string, content []byte) *corev1.ConfigMap { |
||||||
|
cmName := strings.Split(filename, ".")[0] |
||||||
|
|
||||||
|
return &corev1.ConfigMap{ |
||||||
|
TypeMeta: metav1.TypeMeta{ |
||||||
|
Kind: "ConfigMap", |
||||||
|
APIVersion: corev1.SchemeGroupVersion.String(), |
||||||
|
}, |
||||||
|
ObjectMeta: metav1.ObjectMeta{ |
||||||
|
Name: cmName, |
||||||
|
Namespace: managedConfigNamespace, |
||||||
|
Labels: map[string]string{ |
||||||
|
labelConsoleDashboard: "true", |
||||||
|
}, |
||||||
|
}, |
||||||
|
Data: map[string]string{ |
||||||
|
filename: string(content), |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func newDashboardPrometheusRule(namespace string, spec *monitoringv1.PrometheusRuleSpec) (*monitoringv1.PrometheusRule, error) { |
||||||
|
return &monitoringv1.PrometheusRule{ |
||||||
|
TypeMeta: metav1.TypeMeta{ |
||||||
|
Kind: "PrometheusRule", |
||||||
|
APIVersion: monitoringv1.SchemeGroupVersion.String(), |
||||||
|
}, |
||||||
|
ObjectMeta: metav1.ObjectMeta{ |
||||||
|
Name: dashboardPrometheusRulesName, |
||||||
|
Namespace: namespace, |
||||||
|
}, |
||||||
|
Spec: *spec, |
||||||
|
}, nil |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package openshift |
||||||
|
|
||||||
|
import ( |
||||||
|
"testing" |
||||||
|
|
||||||
|
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" |
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
corev1 "k8s.io/api/core/v1" |
||||||
|
) |
||||||
|
|
||||||
|
func TestBuildDashboards_ReturnsDashboardConfigMaps(t *testing.T) { |
||||||
|
objs, err := BuildDashboards("test") |
||||||
|
require.NoError(t, err) |
||||||
|
|
||||||
|
for _, d := range objs { |
||||||
|
switch d.(type) { |
||||||
|
case *corev1.ConfigMap: |
||||||
|
require.Equal(t, d.GetNamespace(), managedConfigNamespace) |
||||||
|
require.Contains(t, d.GetLabels(), labelConsoleDashboard) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func TestBuildDashboards_ReturnsPrometheusRules(t *testing.T) { |
||||||
|
objs, err := BuildDashboards("test") |
||||||
|
require.NoError(t, err) |
||||||
|
|
||||||
|
rules := objs[len(objs)-1].(*monitoringv1.PrometheusRule) |
||||||
|
require.Equal(t, rules.GetName(), dashboardPrometheusRulesName) |
||||||
|
require.Equal(t, rules.GetNamespace(), "test") |
||||||
|
require.NotNil(t, rules.Spec) |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
package dashboards |
||||||
|
|
||||||
|
import ( |
||||||
|
"embed" |
||||||
|
"encoding/json" |
||||||
|
"io/fs" |
||||||
|
|
||||||
|
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
staticDir = "static" |
||||||
|
lokiStackDashboardRulesFile = "grafana-dashboard-lokistack-rules.json" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
//go:embed static/*.json
|
||||||
|
lokiStackDashboards embed.FS |
||||||
|
dashboardMap map[string][]byte |
||||||
|
dashboardRules *monitoringv1.PrometheusRuleSpec |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
var err error |
||||||
|
subDir, err := fs.Sub(lokiStackDashboards, staticDir) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
|
||||||
|
jsonFiles, err := fs.Glob(subDir, "*.json") |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
|
||||||
|
dashboardMap = map[string][]byte{} |
||||||
|
for _, file := range jsonFiles { |
||||||
|
var content []byte |
||||||
|
content, err = fs.ReadFile(subDir, file) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
|
||||||
|
switch file { |
||||||
|
case lokiStackDashboardRulesFile: |
||||||
|
err := json.Unmarshal(content, &dashboardRules) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
|
||||||
|
default: |
||||||
|
dashboardMap[file] = content |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Content returns the byte slices one for each LokiStack dashboard
|
||||||
|
// and a separate byte slice for the recording rules from the embedded filesystem.
|
||||||
|
func Content() (map[string][]byte, *monitoringv1.PrometheusRuleSpec) { |
||||||
|
return dashboardMap, dashboardRules |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package dashboards |
||||||
|
|
||||||
|
import ( |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
lokiStackChunkDashboardFile = "grafana-dashboard-lokistack-chunks.json" |
||||||
|
lokiStackReadsDashboardFile = "grafana-dashboard-lokistack-reads.json" |
||||||
|
lokiStackWritesDashboardFile = "grafana-dashboard-lokistack-writes.json" |
||||||
|
lokiStackRetentionDashboardFile = "grafana-dashboard-lokistack-retention.json" |
||||||
|
) |
||||||
|
|
||||||
|
func TestContent(t *testing.T) { |
||||||
|
m, r := Content() |
||||||
|
require.Len(t, m, 4) |
||||||
|
require.Equal(t, dashboardMap, m) |
||||||
|
require.Equal(t, dashboardRules, r) |
||||||
|
|
||||||
|
require.Contains(t, m, lokiStackChunkDashboardFile) |
||||||
|
require.Contains(t, m, lokiStackReadsDashboardFile) |
||||||
|
require.Contains(t, m, lokiStackWritesDashboardFile) |
||||||
|
require.Contains(t, m, lokiStackRetentionDashboardFile) |
||||||
|
require.NotContains(t, m, lokiStackDashboardRulesFile) |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,680 @@ |
|||||||
|
{ |
||||||
|
"annotations": { |
||||||
|
"list": [ ] |
||||||
|
}, |
||||||
|
"editable": true, |
||||||
|
"gnetId": null, |
||||||
|
"graphTooltip": 0, |
||||||
|
"hideControls": false, |
||||||
|
"links": [ |
||||||
|
{ |
||||||
|
"asDropdown": true, |
||||||
|
"icon": "external link", |
||||||
|
"includeVars": true, |
||||||
|
"keepTime": true, |
||||||
|
"tags": [ |
||||||
|
"loki" |
||||||
|
], |
||||||
|
"targetBlank": false, |
||||||
|
"title": "Loki Dashboards", |
||||||
|
"type": "dashboards" |
||||||
|
} |
||||||
|
], |
||||||
|
"refresh": "10s", |
||||||
|
"rows": [ |
||||||
|
{ |
||||||
|
"collapse": false, |
||||||
|
"height": "250px", |
||||||
|
"panels": [ |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 1, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ |
||||||
|
{ |
||||||
|
"alias": "request", |
||||||
|
"color": "#FFC000", |
||||||
|
"fill": 0 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"alias": "limit", |
||||||
|
"color": "#E02F44", |
||||||
|
"fill": 0 |
||||||
|
} |
||||||
|
], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 4, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{ namespace=~\"$namespace\", container=~\".+-compactor\"}[$__rate_interval]))", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{pod}}", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "min(kube_pod_container_resource_requests{ namespace=~\"$namespace\", container=~\".+-compactor\", resource=\"cpu\"} > 0)", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "request", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "min(container_spec_cpu_quota{ namespace=~\"$namespace\", container=~\".+-compactor\"} / container_spec_cpu_period{ namespace=~\"$namespace\", container=~\".+-compactor\"})", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "limit", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "CPU", |
||||||
|
"tooltip": { |
||||||
|
"sort": 2 |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 2, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ |
||||||
|
{ |
||||||
|
"alias": "request", |
||||||
|
"color": "#FFC000", |
||||||
|
"fill": 0 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"alias": "limit", |
||||||
|
"color": "#E02F44", |
||||||
|
"fill": 0 |
||||||
|
} |
||||||
|
], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 4, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "max by(pod) (container_memory_working_set_bytes{ namespace=~\"$namespace\", container=~\".+-compactor\"})", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{pod}}", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "min(kube_pod_container_resource_requests{ namespace=~\"$namespace\", container=~\".+-compactor\", resource=\"memory\"} > 0)", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "request", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "min(container_spec_memory_limit_bytes{ namespace=~\"$namespace\", container=~\".+-compactor\"} > 0)", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "limit", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Memory (workingset)", |
||||||
|
"tooltip": { |
||||||
|
"sort": 2 |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "bytes", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 3, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 4, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "sum by(pod) (go_memstats_heap_inuse_bytes{ namespace=\"$namespace\", job=~\".+-compactor-http\"})", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{pod}}", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Memory (go heap inuse)", |
||||||
|
"tooltip": { |
||||||
|
"sort": 2 |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "bytes", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
], |
||||||
|
"repeat": null, |
||||||
|
"repeatIteration": null, |
||||||
|
"repeatRowId": null, |
||||||
|
"showTitle": true, |
||||||
|
"title": "Resource Usage", |
||||||
|
"titleSize": "h6" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"collapse": false, |
||||||
|
"height": "250px", |
||||||
|
"panels": [ |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fieldConfig": { |
||||||
|
"defaults": { |
||||||
|
"color": { |
||||||
|
"fixedColor": "blue", |
||||||
|
"mode": "fixed" |
||||||
|
}, |
||||||
|
"custom": { }, |
||||||
|
"thresholds": { |
||||||
|
"mode": "absolute", |
||||||
|
"steps": [ |
||||||
|
{ |
||||||
|
"color": "green", |
||||||
|
"value": null |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"unit": "dateTimeFromNow" |
||||||
|
} |
||||||
|
}, |
||||||
|
"fill": 1, |
||||||
|
"id": 4, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"options": { |
||||||
|
"colorMode": "value", |
||||||
|
"graphMode": "area", |
||||||
|
"justifyMode": "auto", |
||||||
|
"orientation": "auto", |
||||||
|
"reduceOptions": { |
||||||
|
"calcs": [ |
||||||
|
"lastNotNull" |
||||||
|
], |
||||||
|
"fields": "", |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"text": { }, |
||||||
|
"textMode": "auto" |
||||||
|
}, |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 4, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "loki_boltdb_shipper_compact_tables_operation_last_successful_run_timestamp_seconds{ namespace=~\"$namespace\"} * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"instant": true, |
||||||
|
"refId": "A" |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Last Compact and Mark Operation Success", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "stat", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 5, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 4, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "loki_boltdb_shipper_compact_tables_operation_duration_seconds{ namespace=~\"$namespace\"}", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "duration", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Compact and Mark Operations Duration", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "s", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 6, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 4, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "sum by (status)(rate(loki_boltdb_shipper_compact_tables_operation_total{ namespace=~\"$namespace\"}[$__rate_interval]))", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{success}}", |
||||||
|
"legendLink": null, |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Compact and Mark Operations Per Status", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
], |
||||||
|
"repeat": null, |
||||||
|
"repeatIteration": null, |
||||||
|
"repeatRowId": null, |
||||||
|
"showTitle": true, |
||||||
|
"title": "Compact and Mark", |
||||||
|
"titleSize": "h6" |
||||||
|
} |
||||||
|
], |
||||||
|
"schemaVersion": 14, |
||||||
|
"style": "dark", |
||||||
|
"tags": [ |
||||||
|
"loki", |
||||||
|
"logging", |
||||||
|
"loki-mixin" |
||||||
|
], |
||||||
|
"templating": { |
||||||
|
"list": [ |
||||||
|
{ |
||||||
|
"current": { |
||||||
|
"selected": true, |
||||||
|
"text": "default", |
||||||
|
"value": "default" |
||||||
|
}, |
||||||
|
"hide": 0, |
||||||
|
"label": "Data Source", |
||||||
|
"name": "datasource", |
||||||
|
"options": [ ], |
||||||
|
"query": "prometheus", |
||||||
|
"refresh": 1, |
||||||
|
"regex": "", |
||||||
|
"type": "datasource" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"allValue": null, |
||||||
|
"current": { |
||||||
|
"selected": false, |
||||||
|
"text": "openshift-logging", |
||||||
|
"value": "openshift-logging" |
||||||
|
}, |
||||||
|
"datasource": "${datasource}", |
||||||
|
"definition": "label_values(loki_build_info, namespace)", |
||||||
|
"hide": 0, |
||||||
|
"includeAll": false, |
||||||
|
"label": "namespace", |
||||||
|
"multi": false, |
||||||
|
"name": "namespace", |
||||||
|
"options": [ ], |
||||||
|
"query": "label_values(loki_build_info, namespace)", |
||||||
|
"refresh": 1, |
||||||
|
"regex": "", |
||||||
|
"sort": 2, |
||||||
|
"tagValuesQuery": "", |
||||||
|
"tags": [ ], |
||||||
|
"tagsQuery": "", |
||||||
|
"type": "query", |
||||||
|
"useTags": false |
||||||
|
}, |
||||||
|
{ |
||||||
|
"hide": 0, |
||||||
|
"label": null, |
||||||
|
"name": "loki_datasource", |
||||||
|
"options": [ ], |
||||||
|
"query": "loki", |
||||||
|
"refresh": 1, |
||||||
|
"regex": "", |
||||||
|
"type": "datasource" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"time": { |
||||||
|
"from": "now-1h", |
||||||
|
"to": "now" |
||||||
|
}, |
||||||
|
"timepicker": { |
||||||
|
"refresh_intervals": [ |
||||||
|
"5s", |
||||||
|
"10s", |
||||||
|
"30s", |
||||||
|
"1m", |
||||||
|
"5m", |
||||||
|
"15m", |
||||||
|
"30m", |
||||||
|
"1h", |
||||||
|
"2h", |
||||||
|
"1d" |
||||||
|
], |
||||||
|
"time_options": [ |
||||||
|
"5m", |
||||||
|
"15m", |
||||||
|
"1h", |
||||||
|
"6h", |
||||||
|
"12h", |
||||||
|
"24h", |
||||||
|
"2d", |
||||||
|
"7d", |
||||||
|
"30d" |
||||||
|
] |
||||||
|
}, |
||||||
|
"timezone": "utc", |
||||||
|
"title": "OpenShift Logging / LokiStack / Retention", |
||||||
|
"uid": "RetCujSHzC8gd9i5fck9a3v9n2EvTzA", |
||||||
|
"version": 0 |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
{ |
||||||
|
"groups": [ |
||||||
|
{ |
||||||
|
"name": "loki_rules", |
||||||
|
"rules": [ |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job, route)", |
||||||
|
"record": "job_route:loki_request_duration_seconds_bucket:sum_rate" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_request_duration_seconds_sum[1m])) by (job, route)", |
||||||
|
"record": "job_route:loki_request_duration_seconds_sum:sum_rate" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_request_duration_seconds_count[1m])) by (job, route)", |
||||||
|
"record": "job_route:loki_request_duration_seconds_count:sum_rate" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, namespace, job, route)", |
||||||
|
"record": "namespace_job_route:loki_request_duration_seconds_bucket:sum_rate" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_request_duration_seconds_sum[1m])) by (namespace, job, route)", |
||||||
|
"record": "namespace_job_route:loki_request_duration_seconds_sum:sum_rate" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route)", |
||||||
|
"record": "namespace_job_route:loki_request_duration_seconds_count:sum_rate" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,862 @@ |
|||||||
|
{ |
||||||
|
"annotations": { |
||||||
|
"list": [ ] |
||||||
|
}, |
||||||
|
"editable": true, |
||||||
|
"gnetId": null, |
||||||
|
"graphTooltip": 0, |
||||||
|
"hideControls": false, |
||||||
|
"links": [ |
||||||
|
{ |
||||||
|
"asDropdown": true, |
||||||
|
"icon": "external link", |
||||||
|
"includeVars": true, |
||||||
|
"keepTime": true, |
||||||
|
"tags": [ |
||||||
|
"loki" |
||||||
|
], |
||||||
|
"targetBlank": false, |
||||||
|
"title": "Loki Dashboards", |
||||||
|
"type": "dashboards" |
||||||
|
} |
||||||
|
], |
||||||
|
"refresh": "10s", |
||||||
|
"rows": [ |
||||||
|
{ |
||||||
|
"collapse": false, |
||||||
|
"height": "250px", |
||||||
|
"panels": [ |
||||||
|
{ |
||||||
|
"aliasColors": { |
||||||
|
"1xx": "#EAB839", |
||||||
|
"2xx": "#7EB26D", |
||||||
|
"3xx": "#6ED0E0", |
||||||
|
"4xx": "#EF843C", |
||||||
|
"5xx": "#E24D42", |
||||||
|
"error": "#E24D42", |
||||||
|
"success": "#7EB26D" |
||||||
|
}, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 10, |
||||||
|
"id": 1, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 0, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": true, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{namespace=\"$namespace\",job=~\".+-distributor-http\",route=\"loki_api_v1_push\", route=~\"api_prom_push|loki_api_v1_push|/httpgrpc.HTTP/Handle\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{status}}", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "QPS", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 2, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.99, sum by (le) (namespace_job_route:loki_request_duration_seconds_bucket:sum_rate{namespace=\"$namespace\", job=~\".+-distributor-http\", route=\"loki_api_v1_push\"})) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "99th Percentile", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.50, sum by (le) (namespace_job_route:loki_request_duration_seconds_bucket:sum_rate{namespace=\"$namespace\", job=~\".+-distributor-http\", route=\"loki_api_v1_push\"})) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "50th Percentile", |
||||||
|
"refId": "B", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "1e3 * sum(namespace_job_route:loki_request_duration_seconds_sum:sum_rate{namespace=\"$namespace\", job=~\".+-distributor-http\", route=\"loki_api_v1_push\"}) / sum(namespace_job_route:loki_request_duration_seconds_count:sum_rate{namespace=\"$namespace\", job=~\".+-distributor-http\", route=\"loki_api_v1_push\"})", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "Average", |
||||||
|
"refId": "C", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Latency", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "ms", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
], |
||||||
|
"repeat": null, |
||||||
|
"repeatIteration": null, |
||||||
|
"repeatRowId": null, |
||||||
|
"showTitle": true, |
||||||
|
"title": "Distributor", |
||||||
|
"titleSize": "h6" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"collapse": false, |
||||||
|
"height": "250px", |
||||||
|
"panels": [ |
||||||
|
{ |
||||||
|
"aliasColors": { |
||||||
|
"1xx": "#EAB839", |
||||||
|
"2xx": "#7EB26D", |
||||||
|
"3xx": "#6ED0E0", |
||||||
|
"4xx": "#EF843C", |
||||||
|
"5xx": "#E24D42", |
||||||
|
"error": "#E24D42", |
||||||
|
"success": "#7EB26D" |
||||||
|
}, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 10, |
||||||
|
"id": 5, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 0, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": true, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{namespace=\"$namespace\",job=~\".+-ingester-http\", route=\"/logproto.Pusher/Push\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{status}}", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "QPS", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 6, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.99, sum by (le) (namespace_job_route:loki_request_duration_seconds_bucket:sum_rate{namespace=\"$namespace\", job=~\".+-ingester-http\", route=\"/logproto.Pusher/Push\"})) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "99th Percentile", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.50, sum by (le) (namespace_job_route:loki_request_duration_seconds_bucket:sum_rate{namespace=\"$namespace\", job=~\".+-ingester-http\", route=\"/logproto.Pusher/Push\"})) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "50th Percentile", |
||||||
|
"refId": "B", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "1e3 * sum(namespace_job_route:loki_request_duration_seconds_sum:sum_rate{namespace=\"$namespace\", job=~\".+-ingester-http\", route=\"/logproto.Pusher/Push\"}) / sum(namespace_job_route:loki_request_duration_seconds_count:sum_rate{namespace=\"$namespace\", job=~\".+-ingester-http\", route=\"/logproto.Pusher/Push\"})", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "Average", |
||||||
|
"refId": "C", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Latency", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "ms", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
], |
||||||
|
"repeat": null, |
||||||
|
"repeatIteration": null, |
||||||
|
"repeatRowId": null, |
||||||
|
"showTitle": true, |
||||||
|
"title": "Ingester", |
||||||
|
"titleSize": "h6" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"collapse": false, |
||||||
|
"height": "250px", |
||||||
|
"panels": [ |
||||||
|
{ |
||||||
|
"aliasColors": { |
||||||
|
"1xx": "#EAB839", |
||||||
|
"2xx": "#7EB26D", |
||||||
|
"3xx": "#6ED0E0", |
||||||
|
"4xx": "#EF843C", |
||||||
|
"5xx": "#E24D42", |
||||||
|
"error": "#E24D42", |
||||||
|
"success": "#7EB26D" |
||||||
|
}, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 10, |
||||||
|
"id": 7, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 0, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": true, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "sum by (status) (\n label_replace(label_replace(rate(loki_index_request_duration_seconds_count{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"index_chunk\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{status}}", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "QPS", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 8, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.99, sum(rate(loki_index_request_duration_seconds_bucket{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"index_chunk\"}[$__rate_interval])) by (le)) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "99th Percentile", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.50, sum(rate(loki_index_request_duration_seconds_bucket{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"index_chunk\"}[$__rate_interval])) by (le)) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "50th Percentile", |
||||||
|
"refId": "B", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_index_request_duration_seconds_sum{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"index_chunk\"}[$__rate_interval])) * 1e3 / sum(rate(loki_index_request_duration_seconds_count{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"index_chunk\"}[$__rate_interval]))", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "Average", |
||||||
|
"refId": "C", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Latency", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "ms", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
], |
||||||
|
"repeat": null, |
||||||
|
"repeatIteration": null, |
||||||
|
"repeatRowId": null, |
||||||
|
"showTitle": true, |
||||||
|
"title": "Index", |
||||||
|
"titleSize": "h6" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"collapse": false, |
||||||
|
"height": "250px", |
||||||
|
"panels": [ |
||||||
|
{ |
||||||
|
"aliasColors": { |
||||||
|
"1xx": "#EAB839", |
||||||
|
"2xx": "#7EB26D", |
||||||
|
"3xx": "#6ED0E0", |
||||||
|
"4xx": "#EF843C", |
||||||
|
"5xx": "#E24D42", |
||||||
|
"error": "#E24D42", |
||||||
|
"success": "#7EB26D" |
||||||
|
}, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 10, |
||||||
|
"id": 9, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 0, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": true, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "sum by (status) (\n label_replace(label_replace(rate(loki_boltdb_shipper_request_duration_seconds_count{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"WRITE\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "{{status}}", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "QPS", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"aliasColors": { }, |
||||||
|
"bars": false, |
||||||
|
"dashLength": 10, |
||||||
|
"dashes": false, |
||||||
|
"datasource": "$datasource", |
||||||
|
"fill": 1, |
||||||
|
"id": 10, |
||||||
|
"legend": { |
||||||
|
"avg": false, |
||||||
|
"current": false, |
||||||
|
"max": false, |
||||||
|
"min": false, |
||||||
|
"show": true, |
||||||
|
"total": false, |
||||||
|
"values": false |
||||||
|
}, |
||||||
|
"lines": true, |
||||||
|
"linewidth": 1, |
||||||
|
"links": [ ], |
||||||
|
"nullPointMode": "null as zero", |
||||||
|
"percentage": false, |
||||||
|
"pointradius": 5, |
||||||
|
"points": false, |
||||||
|
"renderer": "flot", |
||||||
|
"seriesOverrides": [ ], |
||||||
|
"spaceLength": 10, |
||||||
|
"span": 6, |
||||||
|
"stack": false, |
||||||
|
"steppedLine": false, |
||||||
|
"targets": [ |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "99th Percentile", |
||||||
|
"refId": "A", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "50th Percentile", |
||||||
|
"refId": "B", |
||||||
|
"step": 10 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_sum{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"WRITE\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_request_duration_seconds_count{namespace=\"$namespace\",job=~\".+-ingester-http\", operation=\"WRITE\"}[$__rate_interval]))", |
||||||
|
"format": "time_series", |
||||||
|
"intervalFactor": 2, |
||||||
|
"legendFormat": "Average", |
||||||
|
"refId": "C", |
||||||
|
"step": 10 |
||||||
|
} |
||||||
|
], |
||||||
|
"thresholds": [ ], |
||||||
|
"timeFrom": null, |
||||||
|
"timeShift": null, |
||||||
|
"title": "Latency", |
||||||
|
"tooltip": { |
||||||
|
"shared": true, |
||||||
|
"sort": 2, |
||||||
|
"value_type": "individual" |
||||||
|
}, |
||||||
|
"type": "graph", |
||||||
|
"xaxis": { |
||||||
|
"buckets": null, |
||||||
|
"mode": "time", |
||||||
|
"name": null, |
||||||
|
"show": true, |
||||||
|
"values": [ ] |
||||||
|
}, |
||||||
|
"yaxes": [ |
||||||
|
{ |
||||||
|
"format": "ms", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": 0, |
||||||
|
"show": true |
||||||
|
}, |
||||||
|
{ |
||||||
|
"format": "short", |
||||||
|
"label": null, |
||||||
|
"logBase": 1, |
||||||
|
"max": null, |
||||||
|
"min": null, |
||||||
|
"show": false |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
], |
||||||
|
"repeat": null, |
||||||
|
"repeatIteration": null, |
||||||
|
"repeatRowId": null, |
||||||
|
"showTitle": true, |
||||||
|
"title": "BoltDB Shipper", |
||||||
|
"titleSize": "h6" |
||||||
|
} |
||||||
|
], |
||||||
|
"schemaVersion": 14, |
||||||
|
"style": "dark", |
||||||
|
"tags": [ |
||||||
|
"loki", |
||||||
|
"logging", |
||||||
|
"loki-mixin" |
||||||
|
], |
||||||
|
"templating": { |
||||||
|
"list": [ |
||||||
|
{ |
||||||
|
"current": { |
||||||
|
"selected": true, |
||||||
|
"text": "default", |
||||||
|
"value": "default" |
||||||
|
}, |
||||||
|
"hide": 0, |
||||||
|
"label": "Data Source", |
||||||
|
"name": "datasource", |
||||||
|
"options": [ ], |
||||||
|
"query": "prometheus", |
||||||
|
"refresh": 1, |
||||||
|
"regex": "", |
||||||
|
"type": "datasource" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"allValue": null, |
||||||
|
"current": { |
||||||
|
"selected": false, |
||||||
|
"text": "openshift-logging", |
||||||
|
"value": "openshift-logging" |
||||||
|
}, |
||||||
|
"datasource": "${datasource}", |
||||||
|
"definition": "label_values(loki_build_info, namespace)", |
||||||
|
"hide": 0, |
||||||
|
"includeAll": false, |
||||||
|
"label": "namespace", |
||||||
|
"multi": false, |
||||||
|
"name": "namespace", |
||||||
|
"options": [ ], |
||||||
|
"query": "label_values(loki_build_info, namespace)", |
||||||
|
"refresh": 1, |
||||||
|
"regex": "", |
||||||
|
"sort": 2, |
||||||
|
"tagValuesQuery": "", |
||||||
|
"tags": [ ], |
||||||
|
"tagsQuery": "", |
||||||
|
"type": "query", |
||||||
|
"useTags": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"time": { |
||||||
|
"from": "now-1h", |
||||||
|
"to": "now" |
||||||
|
}, |
||||||
|
"timepicker": { |
||||||
|
"refresh_intervals": [ |
||||||
|
"5s", |
||||||
|
"10s", |
||||||
|
"30s", |
||||||
|
"1m", |
||||||
|
"5m", |
||||||
|
"15m", |
||||||
|
"30m", |
||||||
|
"1h", |
||||||
|
"2h", |
||||||
|
"1d" |
||||||
|
], |
||||||
|
"time_options": [ |
||||||
|
"5m", |
||||||
|
"15m", |
||||||
|
"1h", |
||||||
|
"6h", |
||||||
|
"12h", |
||||||
|
"24h", |
||||||
|
"2d", |
||||||
|
"7d", |
||||||
|
"30d" |
||||||
|
] |
||||||
|
}, |
||||||
|
"timezone": "utc", |
||||||
|
"title": "OpenShift Logging / LokiStack / Writes", |
||||||
|
"uid": "F6nRYKuXmFVpVSFQmXr7cgXy5j7UNr", |
||||||
|
"version": 0 |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package operator |
||||||
|
|
||||||
|
import "os" |
||||||
|
|
||||||
|
const inClusterNamespaceFile = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" |
||||||
|
|
||||||
|
// GetNamespace returns the namespace the operator is running in from
|
||||||
|
// the `/var/run/secrets/kubernetes.io/serviceaccount/namespace` file.
|
||||||
|
func GetNamespace() (string, error) { |
||||||
|
b, err := os.ReadFile(inClusterNamespaceFile) |
||||||
|
if err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
|
||||||
|
return string(b), nil |
||||||
|
} |
@ -0,0 +1,219 @@ |
|||||||
|
local utils = (import 'github.com/grafana/jsonnet-libs/mixin-utils/utils.libsonnet'); |
||||||
|
|
||||||
|
{ |
||||||
|
loki: { |
||||||
|
local withDatasource = function(ds) ds + ( |
||||||
|
if ds.name == 'datasource' then { |
||||||
|
query: 'prometheus', |
||||||
|
current: { |
||||||
|
selected: true, |
||||||
|
text: 'default', |
||||||
|
value: 'default', |
||||||
|
}, |
||||||
|
} else {} |
||||||
|
), |
||||||
|
|
||||||
|
local withNamespace = function(ns) ns + ( |
||||||
|
if ns.label == 'namespace' then { |
||||||
|
datasource: '${datasource}', |
||||||
|
current: { |
||||||
|
selected: false, |
||||||
|
text: 'openshift-logging', |
||||||
|
value: 'openshift-logging', |
||||||
|
}, |
||||||
|
definition: 'label_values(loki_build_info, namespace)', |
||||||
|
query: 'label_values(loki_build_info, namespace)', |
||||||
|
} else {} |
||||||
|
), |
||||||
|
|
||||||
|
local defaultLokiTags = function(t) |
||||||
|
std.uniq(t + ['logging', 'loki-mixin']), |
||||||
|
|
||||||
|
local replaceMatchers = function(replacements) |
||||||
|
function(p) p { |
||||||
|
targets: [ |
||||||
|
t { |
||||||
|
expr: std.foldl(function(x, rp) std.strReplace(x, rp.from, rp.to), replacements, t.expr), |
||||||
|
} |
||||||
|
for t in p.targets |
||||||
|
if std.objectHas(p, 'targets') |
||||||
|
], |
||||||
|
}, |
||||||
|
|
||||||
|
// dropPanels removes unnecessary panels from the loki dashboards |
||||||
|
// that are of obsolete usage on our AWS-based deployment environment. |
||||||
|
local dropPanels = function(panels, dropList, fn) |
||||||
|
[ |
||||||
|
p |
||||||
|
for p in panels |
||||||
|
if !std.member(dropList, p.title) && fn(p) |
||||||
|
], |
||||||
|
|
||||||
|
// mapPanels applies recursively a set of functions over all panels. |
||||||
|
// Note: A Grafana dashboard panel can include other panels. |
||||||
|
// Example: Replace job label in expression and add axis units for all panels. |
||||||
|
local mapPanels = function(funcs, panels) |
||||||
|
[ |
||||||
|
// Transform the current panel by applying all transformer funcs. |
||||||
|
// Keep the last version after foldl ends. |
||||||
|
std.foldl(function(agg, fn) fn(agg), funcs, p) + ( |
||||||
|
// Recursively apply all transformer functions to any |
||||||
|
// children panels. |
||||||
|
if std.objectHas(p, 'panels') then { |
||||||
|
panels: mapPanels(funcs, p.panels), |
||||||
|
} else {} |
||||||
|
) |
||||||
|
for p in panels |
||||||
|
], |
||||||
|
|
||||||
|
// mapTemplateParameters applies a static list of transformer functions to |
||||||
|
// all dashboard template parameters. The static list includes: |
||||||
|
// - cluster-prometheus as datasource based on environment. |
||||||
|
local mapTemplateParameters = function(ls) |
||||||
|
[ |
||||||
|
std.foldl(function(x, fn) fn(x), [withDatasource, withNamespace], item) |
||||||
|
for item in ls |
||||||
|
if item.name != 'cluster' |
||||||
|
], |
||||||
|
|
||||||
|
local dropRules = function(rules, dropList) |
||||||
|
[ |
||||||
|
r |
||||||
|
for r in rules |
||||||
|
if !std.member(dropList, r.record) |
||||||
|
], |
||||||
|
|
||||||
|
prometheusRules+: { |
||||||
|
local dropList = [ |
||||||
|
'cluster_job:loki_request_duration_seconds:99quantile', |
||||||
|
'cluster_job:loki_request_duration_seconds:50quantile', |
||||||
|
'cluster_job:loki_request_duration_seconds:avg', |
||||||
|
'cluster_job:loki_request_duration_seconds_bucket:sum_rate', |
||||||
|
'cluster_job:loki_request_duration_seconds_sum:sum_rate', |
||||||
|
'cluster_job:loki_request_duration_seconds_count:sum_rate', |
||||||
|
'cluster_job_route:loki_request_duration_seconds:99quantile', |
||||||
|
'cluster_job_route:loki_request_duration_seconds:50quantile', |
||||||
|
'cluster_job_route:loki_request_duration_seconds:avg', |
||||||
|
'cluster_namespace_job_route:loki_request_duration_seconds:99quantile', |
||||||
|
'cluster_namespace_job_route:loki_request_duration_seconds:50quantile', |
||||||
|
'cluster_namespace_job_route:loki_request_duration_seconds:avg', |
||||||
|
], |
||||||
|
groups: [ |
||||||
|
g { |
||||||
|
rules: [ |
||||||
|
r { |
||||||
|
expr: std.strReplace(r.expr, 'cluster, ', ''), |
||||||
|
record: std.strReplace(r.record, 'cluster_', ''), |
||||||
|
} |
||||||
|
for r in dropRules(g.rules, dropList) |
||||||
|
], |
||||||
|
} |
||||||
|
for g in super.groups |
||||||
|
], |
||||||
|
}, |
||||||
|
|
||||||
|
local dropHistograms = function(p) |
||||||
|
local elems = std.filter(function(p) p.type == 'heatmap', p.panels); |
||||||
|
std.length(elems) == 0, |
||||||
|
|
||||||
|
grafanaDashboards+: { |
||||||
|
'loki-retention.json'+: { |
||||||
|
local dropList = ['Logs', 'Per Table Marker', 'Sweeper', ''], |
||||||
|
local replacements = [ |
||||||
|
{ from: 'cluster=~"$cluster",', to: '' }, |
||||||
|
{ from: 'container="compactor"', to: 'container=~".+-compactor"' }, |
||||||
|
{ from: 'job=~"($namespace)/compactor"', to: 'namespace="$namespace", job=~".+-compactor-http"' }, |
||||||
|
], |
||||||
|
uid: 'RetCujSHzC8gd9i5fck9a3v9n2EvTzA', |
||||||
|
title: 'OpenShift Logging / LokiStack / Retention', |
||||||
|
tags: defaultLokiTags(super.tags), |
||||||
|
rows: [ |
||||||
|
r { |
||||||
|
panels: mapPanels([replaceMatchers(replacements)], r.panels), |
||||||
|
} |
||||||
|
for r in dropPanels(super.rows, dropList, function(p) true) |
||||||
|
], |
||||||
|
templating+: { |
||||||
|
list: mapTemplateParameters(super.list), |
||||||
|
}, |
||||||
|
}, |
||||||
|
'loki-chunks.json'+: { |
||||||
|
local dropList = ['Utilization'], |
||||||
|
uid: 'GtCujSHzC8gd9i5fck9a3v9n2EvTzA', |
||||||
|
title: 'OpenShift Logging / LokiStack / Chunks', |
||||||
|
tags: defaultLokiTags(super.tags), |
||||||
|
showMultiCluster:: false, |
||||||
|
namespaceQuery:: 'label_values(loki_build_info, namespace)', |
||||||
|
namespaceType:: 'query', |
||||||
|
labelsSelector:: 'namespace="$namespace", job=~".+-ingester-http"', |
||||||
|
rows: [ |
||||||
|
r |
||||||
|
for r in dropPanels(super.rows, dropList, dropHistograms) |
||||||
|
], |
||||||
|
templating+: { |
||||||
|
list: mapTemplateParameters(super.list), |
||||||
|
}, |
||||||
|
}, |
||||||
|
'loki-reads.json'+: { |
||||||
|
local dropList = ['BigTable', 'Ingester - Zone Aware'], |
||||||
|
|
||||||
|
uid: '62q5jjYwhVSaz4Mcrm8tV3My3gcKED', |
||||||
|
title: 'OpenShift Logging / LokiStack / Reads', |
||||||
|
tags: defaultLokiTags(super.tags), |
||||||
|
showMultiCluster:: false, |
||||||
|
namespaceQuery:: 'label_values(loki_build_info, namespace)', |
||||||
|
namespaceType:: 'query', |
||||||
|
matchers:: { |
||||||
|
cortexgateway:: [], |
||||||
|
queryFrontend:: [ |
||||||
|
utils.selector.eq('namespace', '$namespace'), |
||||||
|
utils.selector.re('job', '.+-query-frontend-http'), |
||||||
|
], |
||||||
|
querier:: [ |
||||||
|
utils.selector.eq('namespace', '$namespace'), |
||||||
|
utils.selector.re('job', '.+-querier-http'), |
||||||
|
], |
||||||
|
ingester:: [ |
||||||
|
utils.selector.eq('namespace', '$namespace'), |
||||||
|
utils.selector.re('job', '.+-ingester-http'), |
||||||
|
], |
||||||
|
ingesterZoneAware:: [], |
||||||
|
querierOrIndexGateway:: [ |
||||||
|
utils.selector.eq('namespace', '$namespace'), |
||||||
|
utils.selector.re('job', '.+-index-gateway-http'), |
||||||
|
], |
||||||
|
}, |
||||||
|
rows: dropPanels(super.rows, dropList, function(p) true), |
||||||
|
templating+: { |
||||||
|
list: mapTemplateParameters(super.list), |
||||||
|
}, |
||||||
|
}, |
||||||
|
'loki-writes.json'+: { |
||||||
|
local dropList = ['Ingester - Zone Aware'], |
||||||
|
uid: 'F6nRYKuXmFVpVSFQmXr7cgXy5j7UNr', |
||||||
|
title: 'OpenShift Logging / LokiStack / Writes', |
||||||
|
tags: defaultLokiTags(super.tags), |
||||||
|
showMultiCluster:: false, |
||||||
|
namespaceQuery:: 'label_values(loki_build_info, namespace)', |
||||||
|
namespaceType:: 'query', |
||||||
|
matchers:: { |
||||||
|
cortexgateway:: [], |
||||||
|
distributor:: [ |
||||||
|
utils.selector.eq('namespace', '$namespace'), |
||||||
|
utils.selector.re('job', '.+-distributor-http'), |
||||||
|
utils.selector.eq('route', 'loki_api_v1_push'), |
||||||
|
], |
||||||
|
ingester:: [ |
||||||
|
utils.selector.eq('namespace', '$namespace'), |
||||||
|
utils.selector.re('job', '.+-ingester-http'), |
||||||
|
], |
||||||
|
ingester_zone:: [], |
||||||
|
}, |
||||||
|
rows: dropPanels(super.rows, dropList, function(p) true), |
||||||
|
templating+: { |
||||||
|
list: mapTemplateParameters(super.list), |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
local cfg = (import 'config.libsonnet'); |
||||||
|
local loki = (import 'github.com/grafana/loki/production/loki-mixin/mixin.libsonnet') + cfg.loki; |
||||||
|
|
||||||
|
{ |
||||||
|
'grafana-dashboard-lokistack-chunks.json': loki.grafanaDashboards['loki-chunks.json'], |
||||||
|
'grafana-dashboard-lokistack-reads.json': loki.grafanaDashboards['loki-reads.json'], |
||||||
|
'grafana-dashboard-lokistack-writes.json': loki.grafanaDashboards['loki-writes.json'], |
||||||
|
'grafana-dashboard-lokistack-retention.json': loki.grafanaDashboards['loki-retention.json'], |
||||||
|
'grafana-dashboard-lokistack-rules.json': loki.prometheusRules, |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
{ |
||||||
|
"version": 1, |
||||||
|
"dependencies": [ |
||||||
|
{ |
||||||
|
"source": { |
||||||
|
"git": { |
||||||
|
"remote": "https://github.com/grafana/loki.git", |
||||||
|
"subdir": "production/loki-mixin" |
||||||
|
} |
||||||
|
}, |
||||||
|
"version": "v2.8.2" |
||||||
|
} |
||||||
|
], |
||||||
|
"legacyImports": true |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
{ |
||||||
|
"version": 1, |
||||||
|
"dependencies": [ |
||||||
|
{ |
||||||
|
"source": { |
||||||
|
"git": { |
||||||
|
"remote": "https://github.com/grafana/grafonnet-lib.git", |
||||||
|
"subdir": "grafonnet" |
||||||
|
} |
||||||
|
}, |
||||||
|
"version": "f0b70307b8e5f12236b277883d998af129a8211f", |
||||||
|
"sum": "342u++/7rViR/zj2jeJOjshzglkZ1SY+hFNuyCBFMdc=" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"source": { |
||||||
|
"git": { |
||||||
|
"remote": "https://github.com/grafana/jsonnet-libs.git", |
||||||
|
"subdir": "grafana-builder" |
||||||
|
} |
||||||
|
}, |
||||||
|
"version": "e8e0f6f536f3397a22a49bd9014a7e0a1dfa151d", |
||||||
|
"sum": "tDR6yT2GVfw0wTU12iZH+m01HrbIr6g/xN+/8nzNkU0=" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"source": { |
||||||
|
"git": { |
||||||
|
"remote": "https://github.com/grafana/jsonnet-libs.git", |
||||||
|
"subdir": "mixin-utils" |
||||||
|
} |
||||||
|
}, |
||||||
|
"version": "e8e0f6f536f3397a22a49bd9014a7e0a1dfa151d", |
||||||
|
"sum": "N1Uz6AJpnQXv4w8F6lxDqMwoT7azPVrpuhJ4N7Oqzcw=" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"source": { |
||||||
|
"git": { |
||||||
|
"remote": "https://github.com/grafana/loki.git", |
||||||
|
"subdir": "production/loki-mixin" |
||||||
|
} |
||||||
|
}, |
||||||
|
"version": "b7ce95402ac5e2712432e8bfc638b262793b8811", |
||||||
|
"sum": "iYoW3v95aLI2zY2zoQvS0TrIe6kVzdIYyCaGUJ0oC+s=" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"source": { |
||||||
|
"git": { |
||||||
|
"remote": "https://github.com/grafana/mimir.git", |
||||||
|
"subdir": "operations/mimir-mixin" |
||||||
|
} |
||||||
|
}, |
||||||
|
"version": "154abe81c5c6b3f263e2b39084f186dd564860af", |
||||||
|
"sum": "xnakaDny0zXG7mhuyUH90swndHinwpt5/RRVFotDqFY=" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"source": { |
||||||
|
"git": { |
||||||
|
"remote": "https://github.com/prometheus-operator/kube-prometheus.git", |
||||||
|
"subdir": "jsonnet/kube-prometheus/lib" |
||||||
|
} |
||||||
|
}, |
||||||
|
"version": "b176baa776a4d6002fe162846dacb424965df1bc", |
||||||
|
"sum": "QKRgrgEZ3k9nLmLCrDBaeIGVqQZf+AvZTcnhdLk3TrA=" |
||||||
|
} |
||||||
|
], |
||||||
|
"legacyImports": false |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
(import 'dashboards.jsonnet') |
Loading…
Reference in new issue