diff --git a/contribs/gnodev/go.mod b/contribs/gnodev/go.mod index f520e2fbb79..b50b043747a 100644 --- a/contribs/gnodev/go.mod +++ b/contribs/gnodev/go.mod @@ -89,6 +89,9 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect diff --git a/contribs/gnodev/go.sum b/contribs/gnodev/go.sum index f4bf32aafd5..da132622c43 100644 --- a/contribs/gnodev/go.sum +++ b/contribs/gnodev/go.sum @@ -252,6 +252,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= diff --git a/contribs/gnofaucet/go.mod b/contribs/gnofaucet/go.mod index 6768a28c848..a41e8328429 100644 --- a/contribs/gnofaucet/go.mod +++ b/contribs/gnofaucet/go.mod @@ -44,6 +44,9 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect diff --git a/contribs/gnofaucet/go.sum b/contribs/gnofaucet/go.sum index ed776d4a0ff..82f6590cb53 100644 --- a/contribs/gnofaucet/go.sum +++ b/contribs/gnofaucet/go.sum @@ -161,6 +161,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= diff --git a/contribs/gnogenesis/go.mod b/contribs/gnogenesis/go.mod index e03ad1dde42..32b23ba9770 100644 --- a/contribs/gnogenesis/go.mod +++ b/contribs/gnogenesis/go.mod @@ -42,6 +42,9 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect diff --git a/contribs/gnogenesis/go.sum b/contribs/gnogenesis/go.sum index e3462f9c431..96304069840 100644 --- a/contribs/gnogenesis/go.sum +++ b/contribs/gnogenesis/go.sum @@ -149,6 +149,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= @@ -159,6 +165,8 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/contribs/gnohealth/go.mod b/contribs/gnohealth/go.mod index 81c0ae7325b..83ef065d91c 100644 --- a/contribs/gnohealth/go.mod +++ b/contribs/gnohealth/go.mod @@ -28,6 +28,9 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect diff --git a/contribs/gnohealth/go.sum b/contribs/gnohealth/go.sum index 3c8b5de45f2..2b8449c1f89 100644 --- a/contribs/gnohealth/go.sum +++ b/contribs/gnohealth/go.sum @@ -130,6 +130,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= @@ -140,6 +146,8 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/contribs/gnokeykc/go.mod b/contribs/gnokeykc/go.mod index 0ecc7b34cf3..511bcd2feaa 100644 --- a/contribs/gnokeykc/go.mod +++ b/contribs/gnokeykc/go.mod @@ -43,6 +43,9 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect diff --git a/contribs/gnokeykc/go.sum b/contribs/gnokeykc/go.sum index 6b4f81dfcf5..8e36ed9d28b 100644 --- a/contribs/gnokeykc/go.sum +++ b/contribs/gnokeykc/go.sum @@ -157,6 +157,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= @@ -167,6 +173,8 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/contribs/gnomigrate/go.mod b/contribs/gnomigrate/go.mod index 0381c6acd01..ce93c197a8a 100644 --- a/contribs/gnomigrate/go.mod +++ b/contribs/gnomigrate/go.mod @@ -37,6 +37,9 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect diff --git a/contribs/gnomigrate/go.sum b/contribs/gnomigrate/go.sum index e3462f9c431..96304069840 100644 --- a/contribs/gnomigrate/go.sum +++ b/contribs/gnomigrate/go.sum @@ -149,6 +149,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= @@ -159,6 +165,8 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/gno.land/cmd/gnoland/start.go b/gno.land/cmd/gnoland/start.go index 4f380031be4..b827b2e8961 100644 --- a/gno.land/cmd/gnoland/start.go +++ b/gno.land/cmd/gnoland/start.go @@ -228,10 +228,29 @@ func execStart(ctx context.Context, c *startCfg, io commands.IO) error { } // Initialize telemetry - if err := telemetry.Init(*cfg.Telemetry); err != nil { + // Return the providers so we can gracefully shutdown them if needed + tracesProvider, metricsProvider, err := telemetry.Init(*cfg.Telemetry, logger) + if err != nil { return fmt.Errorf("unable to initialize telemetry, %w", err) } + if cfg.Telemetry.GracefulShutdownTelemetry { + defer func() { + if tracesProvider != nil { + logger.Info("Gracefully shutting down tracesProvider") + if err := tracesProvider.Shutdown(ctx); err != nil { + logger.Error("unable to shutdown traces provider", "error", err) + } + } + if metricsProvider != nil { + logger.Info("Gracefully shutting down metricsProvider") + if err := metricsProvider.Shutdown(ctx); err != nil { + logger.Error("unable to shutdown metrics provider", "error", err) + } + } + }() + } + // Print the starting graphic if c.logFormat != string(log.JSONFormat) { io.Println(startGraphic) diff --git a/go.mod b/go.mod index 978e2e69d36..c42741c8f1c 100644 --- a/go.mod +++ b/go.mod @@ -33,9 +33,12 @@ require ( go.opentelemetry.io/otel v1.34.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 go.opentelemetry.io/otel/metric v1.34.0 go.opentelemetry.io/otel/sdk v1.34.0 go.opentelemetry.io/otel/sdk/metric v1.34.0 + go.opentelemetry.io/otel/trace v1.34.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 go.uber.org/zap/exp v0.3.0 @@ -63,7 +66,7 @@ require ( github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/go.sum b/go.sum index 5fd4cddd627..6cbf2672e6c 100644 --- a/go.sum +++ b/go.sum @@ -169,6 +169,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= diff --git a/misc/autocounterd/go.mod b/misc/autocounterd/go.mod index 7d9def2b3cc..ca2815210dc 100644 --- a/misc/autocounterd/go.mod +++ b/misc/autocounterd/go.mod @@ -34,6 +34,9 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect diff --git a/misc/autocounterd/go.sum b/misc/autocounterd/go.sum index 6d6d87fa01a..9121238e9dd 100644 --- a/misc/autocounterd/go.sum +++ b/misc/autocounterd/go.sum @@ -149,6 +149,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= @@ -159,6 +165,8 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/misc/loop/go.mod b/misc/loop/go.mod index 7d0252da82c..f47042f50cc 100644 --- a/misc/loop/go.mod +++ b/misc/loop/go.mod @@ -61,6 +61,8 @@ require ( go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect diff --git a/misc/loop/go.sum b/misc/loop/go.sum index c5aed820f5e..f162e824047 100644 --- a/misc/loop/go.sum +++ b/misc/loop/go.sum @@ -201,6 +201,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opw go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= @@ -213,6 +215,8 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/misc/telemetry/collector/collector.yaml b/misc/telemetry/collector/collector.yaml index d258dd025bb..0a88bfd2cf4 100644 --- a/misc/telemetry/collector/collector.yaml +++ b/misc/telemetry/collector/collector.yaml @@ -10,6 +10,10 @@ processors: exporters: prometheus: endpoint: collector:8090 + otlp/tempo: + endpoint: tempo:4317 + tls: + insecure: true service: telemetry: @@ -20,3 +24,7 @@ service: receivers: [ otlp ] processors: [ batch ] exporters: [ prometheus ] + traces: + receivers: [ otlp ] + processors: [ batch ] + exporters: [ otlp/tempo ] diff --git a/misc/telemetry/docker-compose.yml b/misc/telemetry/docker-compose.yml index 89c7a924e08..738e256d18c 100644 --- a/misc/telemetry/docker-compose.yml +++ b/misc/telemetry/docker-compose.yml @@ -4,12 +4,25 @@ services: ports: - "4317:4317" - "4318:4318" - - "8090" + - "8090:8090" volumes: - ./collector/collector.yaml:/etc/otelcol-contrib/config.yaml networks: - gnoland-net + depends_on: + - tempo + - prometheus + tempo: + image: grafana/tempo:latest + command: + - "-config.file=/etc/tempo.yaml" + volumes: + - tempo:/var/tempo + - ./tempo/tempo.yaml:/etc/tempo.yaml + networks: + - gnoland-net + prometheus: image: prom/prometheus:latest command: @@ -35,7 +48,7 @@ services: - "3000:3000" networks: - gnoland-net - + gnoland-val: image: ghcr.io/gnolang/gno/gnoland:master networks: @@ -60,7 +73,8 @@ services: gnoland config init gnoland config set consensus.timeout_commit 1s gnoland config set moniker val000 - gnoland config set telemetry.enabled true + gnoland config set telemetry.metrics_enabled true + gnoland config set telemetry.traces_enabled true gnoland config set telemetry.exporter_endpoint collector:4317 gnoland config set telemetry.service_instance_id val0 gnoland secrets get node_id.id -raw > /gnoroot/shared-data/node_p2p.id @@ -89,7 +103,8 @@ services: gnoland config set consensus.timeout_commit 1s gnoland config set moniker rpc0 gnoland config set rpc.laddr tcp://0.0.0.0:26657 - gnoland config set telemetry.enabled true + gnoland config set telemetry.metrics_enabled true + gnoland config set telemetry.traces_enabled true gnoland config set telemetry.service_instance_id rpc000 gnoland config set telemetry.exporter_endpoint collector:4317 gnoland config set p2p.persistent_peers "$(cat /gnoroot/shared-data/node_p2p.id)@gnoland-val:26656" @@ -114,6 +129,8 @@ networks: driver: bridge volumes: + tempo: + driver: local prometheus: driver: local grafana_data: diff --git a/misc/telemetry/grafana/provisioning/dashboards/gno-otel-dashboards.json b/misc/telemetry/grafana/provisioning/dashboards/gno-otel-metrics-dashboards.json similarity index 100% rename from misc/telemetry/grafana/provisioning/dashboards/gno-otel-dashboards.json rename to misc/telemetry/grafana/provisioning/dashboards/gno-otel-metrics-dashboards.json diff --git a/misc/telemetry/grafana/provisioning/dashboards/gno-otel-traces-dashboards.json b/misc/telemetry/grafana/provisioning/dashboards/gno-otel-traces-dashboards.json new file mode 100644 index 00000000000..b1517667b80 --- /dev/null +++ b/misc/telemetry/grafana/provisioning/dashboards/gno-otel-traces-dashboards.json @@ -0,0 +1,131 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": { + "type": "tempo", + "uid": "tempo" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 19, + "w": 23, + "x": 0, + "y": 0 + }, + "id": 3, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "11.5.2", + "targets": [ + { + "datasource": { + "type": "tempo", + "uid": "tempo" + }, + "filters": [ + { + "id": "fa42c486", + "operator": "=", + "scope": "span" + } + ], + "limit": 20, + "query": "{name=~\"NewHeight: .*${height}.*\"}", + "queryType": "traceql", + "refId": "A", + "tableType": "traces" + } + ], + "title": "Traces", + "type": "table" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "", + "value": "" + }, + "label": "BlockHeight", + "name": "height", + "options": [], + "query": "", + "type": "custom" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Gno Open Telemetry Traces", + "uid": "dee7ykpziof0gf", + "version": 4, + "weekStart": "" +} \ No newline at end of file diff --git a/misc/telemetry/grafana/provisioning/datasources/datasources.yaml b/misc/telemetry/grafana/provisioning/datasources/datasources.yaml index 917b8a544f1..a91a0595d74 100644 --- a/misc/telemetry/grafana/provisioning/datasources/datasources.yaml +++ b/misc/telemetry/grafana/provisioning/datasources/datasources.yaml @@ -11,3 +11,14 @@ datasources: version: 1 editable: true uid: prometheus + + - name: Tempo + type: tempo + access: proxy + orgId: 1 + url: http://tempo:3200 + basicAuth: false + isDefault: false + version: 1 + editable: true + uid: tempo diff --git a/misc/telemetry/prometheus/prometheus.yml b/misc/telemetry/prometheus/prometheus.yml index f92b2a56da7..94e1da0be0e 100644 --- a/misc/telemetry/prometheus/prometheus.yml +++ b/misc/telemetry/prometheus/prometheus.yml @@ -5,3 +5,4 @@ scrape_configs: - job_name: 'opentelemetry' static_configs: - targets: [ 'collector:8090' ] + diff --git a/misc/telemetry/tempo/tempo.yaml b/misc/telemetry/tempo/tempo.yaml new file mode 100644 index 00000000000..568f66d513f --- /dev/null +++ b/misc/telemetry/tempo/tempo.yaml @@ -0,0 +1,26 @@ +server: + http_listen_port: 3200 + +distributor: + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + +ingester: + trace_idle_period: 10s + max_block_bytes: 1_000_000 + max_block_duration: 5m + +storage: + trace: + backend: local + local: + path: /tmp/tempo/traces + +compactor: + compaction: + block_retention: 24h diff --git a/tm2/pkg/bft/consensus/state.go b/tm2/pkg/bft/consensus/state.go index 1d80582988c..80829658b1d 100644 --- a/tm2/pkg/bft/consensus/state.go +++ b/tm2/pkg/bft/consensus/state.go @@ -27,8 +27,15 @@ import ( "github.com/gnolang/gno/tm2/pkg/service" "github.com/gnolang/gno/tm2/pkg/telemetry" "github.com/gnolang/gno/tm2/pkg/telemetry/metrics" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" ) +// ----------------------------------------------------------------------------- +// Tracer +var tracer = telemetry.Tracer("tm2/bft/consensus") + // ----------------------------------------------------------------------------- // Errors @@ -139,6 +146,8 @@ type ConsensusState struct { // closed when we finish shutting down done chan struct{} + + traceCtx context.Context } // StateOption sets an optional parameter on the ConsensusState. @@ -168,6 +177,7 @@ func NewConsensusState( wal: walm.NopWAL{}, walDisabled: config.WALDisabled, } + // set function defaults (may be overwritten before calling Start) cs.decideProposal = cs.defaultDecideProposal cs.doPrevote = cs.defaultDoPrevote @@ -503,14 +513,23 @@ func (cs *ConsensusState) reconstructLastCommit(state sm.State) { // Updates ConsensusState and increments height to match that of state. // The round becomes 0 and cs.Step becomes cstypes.RoundStepNewHeight. func (cs *ConsensusState) updateToState(state sm.State) { + // Here we start a new height, round 0 and RoundStepNewHeight and hence + // start the new trace context and new root span + + // Next desired block height + height := state.LastBlockHeight + 1 + + span := cs.startRootSpan(height) + defer span.End() + if cs.CommitRound > -1 && 0 < cs.Height && cs.Height != state.LastBlockHeight { - panic(fmt.Sprintf("updateToState() expected state height of %v but found %v", + cs.panicWithTrace(span, fmt.Sprintf("updateToState() expected state height of %v but found %v", cs.Height, state.LastBlockHeight)) } if !cs.state.IsEmpty() && cs.state.LastBlockHeight+1 != cs.Height { // This might happen when someone else is mutating cs.state. // Someone forgot to pass in state.Copy() somewhere?! - panic(fmt.Sprintf("Inconsistent cs.state.LastBlockHeight+1 %v vs cs.Height %v", + cs.panicWithTrace(span, fmt.Sprintf("Inconsistent cs.state.LastBlockHeight+1 %v vs cs.Height %v", cs.state.LastBlockHeight+1, cs.Height)) } @@ -530,17 +549,15 @@ func (cs *ConsensusState) updateToState(state sm.State) { lastPrecommits := (*types.VoteSet)(nil) if cs.CommitRound > -1 && cs.Votes != nil { if !cs.Votes.Precommits(cs.CommitRound).HasTwoThirdsMajority() { - panic("updateToState(state) called but last Precommit round didn't have +2/3") + cs.panicWithTrace(span, "updateToState(state) called but last Precommit round didn't have +2/3") } lastPrecommits = cs.Votes.Precommits(cs.CommitRound) } - // Next desired block height - height := state.LastBlockHeight + 1 - // RoundState fields cs.updateHeight(height) cs.updateRoundStep(0, cstypes.RoundStepNewHeight) + if cs.CommitTime.IsZero() { // "Now" makes it easier to sync up dev nodes. // We add timeoutCommit to allow transactions @@ -669,6 +686,12 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) { cs.mtx.Lock() defer cs.mtx.Unlock() + span := cs.addSpan("handleMsg") + span.SetAttributes( + attribute.String("peerID", mi.PeerID.String()), + ) + defer span.End() + var ( added bool err error @@ -713,7 +736,7 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) { // the peer is sending us CatchupCommit precommits. // We could make note of this and help filter in broadcastHasVoteMessage(). default: - cs.Logger.Error("Unknown msg type", "type", reflect.TypeOf(msg)) + cs.logErrorWithTrace(span, fmt.Sprintf("Unknown msg type: %v", reflect.TypeOf(msg))) return } @@ -738,6 +761,9 @@ func (cs *ConsensusState) handleTimeout(ti timeoutInfo, rs cstypes.RoundState) { cs.mtx.Lock() defer cs.mtx.Unlock() + span := cs.addSpan("handleTimeout") + defer span.End() + switch ti.Step { case cstypes.RoundStepNewHeight: // NewRound event fired from enterNewRound. @@ -756,7 +782,7 @@ func (cs *ConsensusState) handleTimeout(ti timeoutInfo, rs cstypes.RoundState) { cs.enterPrecommit(ti.Height, ti.Round) cs.enterNewRound(ti.Height, ti.Round+1) default: - panic(fmt.Sprintf("Invalid timeout step: %v", ti.Step)) + cs.panicWithTrace(span, fmt.Sprintf("Invalid timeout step: %v", ti.Step)) } } @@ -764,6 +790,9 @@ func (cs *ConsensusState) handleTxsAvailable() { cs.mtx.Lock() defer cs.mtx.Unlock() + span := cs.addSpan("handleTxsAvailable") + defer span.End() + // We only need to do this for round 0. if cs.Round != 0 { return @@ -797,6 +826,9 @@ func (cs *ConsensusState) handleTxsAvailable() { // Enter: +2/3 prevotes any or +2/3 precommits for block or any from (height, round) // NOTE: cs.StartTime was already set for height. func (cs *ConsensusState) enterNewRound(height int64, round int) { + span := cs.addSpan("enterNewRound") + defer span.End() + logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != cstypes.RoundStepNewHeight) { @@ -868,6 +900,9 @@ func (cs *ConsensusState) needProofBlock(height int64) bool { // Enter (CreateEmptyBlocks, CreateEmptyBlocksInterval > 0 ): after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval // Enter (!CreateEmptyBlocks) : after enterNewRound(height,round), once txs are in the mempool func (cs *ConsensusState) enterPropose(height int64, round int) { + span := cs.addSpan("enterPropose") + defer span.End() + logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPropose <= cs.Step) { @@ -919,6 +954,9 @@ func (cs *ConsensusState) isProposer(address crypto.Address) bool { } func (cs *ConsensusState) defaultDecideProposal(height int64, round int) { + span := cs.addSpan("defaultDecideProposal") + defer span.End() + var block *types.Block var blockParts *types.PartSet @@ -957,7 +995,10 @@ func (cs *ConsensusState) defaultDecideProposal(height int64, round int) { "proposal timestamp", proposal.Timestamp.Unix(), ) } else if !cs.replayMode { - cs.Logger.Error("enterPropose: Error signing proposal", "height", height, "round", round, "err", err) + cs.logErrorWithTrace( + span, + fmt.Sprintf("enterPropose: Error signing proposal: height %v, round %v, err %v", height, round, err), + ) } } @@ -1013,6 +1054,9 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts // Prevote for LockedBlock if we're locked, or ProposalBlock if valid. // Otherwise vote nil. func (cs *ConsensusState) enterPrevote(height int64, round int) { + span := cs.addSpan("enterPrevote") + defer span.End() + if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevote <= cs.Step) { cs.Logger.Debug(fmt.Sprintf("enterPrevote(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) return @@ -1034,6 +1078,9 @@ func (cs *ConsensusState) enterPrevote(height int64, round int) { } func (cs *ConsensusState) defaultDoPrevote(height int64, round int) { + span := cs.addSpan("defaultDoPrevote") + defer span.End() + logger := cs.Logger.With("height", height, "round", round) // If a block is locked, prevote that. @@ -1054,7 +1101,7 @@ func (cs *ConsensusState) defaultDoPrevote(height int64, round int) { err := cs.state.ValidateBlock(cs.ProposalBlock) if err != nil { // ProposalBlock is invalid, prevote nil. - logger.Error("enterPrevote: ProposalBlock is invalid", "err", err) + cs.logErrorWithTrace(span, fmt.Sprintf("enterPrevote: ProposalBlock is invalid: %v", err)) cs.signAddVote(types.PrevoteType, nil, types.PartSetHeader{}) return } @@ -1068,6 +1115,9 @@ func (cs *ConsensusState) defaultDoPrevote(height int64, round int) { // Enter: any +2/3 prevotes at next round. func (cs *ConsensusState) enterPrevoteWait(height int64, round int) { + span := cs.addSpan("enterPrevoteWait") + defer span.End() + logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevoteWait <= cs.Step) { @@ -1075,7 +1125,7 @@ func (cs *ConsensusState) enterPrevoteWait(height int64, round int) { return } if !cs.Votes.Prevotes(round).HasTwoThirdsAny() { - panic(fmt.Sprintf("enterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes", height, round)) + cs.panicWithTrace(span, fmt.Sprintf("enterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes", height, round)) } logger.Info(fmt.Sprintf("enterPrevoteWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) @@ -1096,6 +1146,9 @@ func (cs *ConsensusState) enterPrevoteWait(height int64, round int) { // else, unlock an existing lock and precommit nil if +2/3 of prevotes were nil, // else, precommit nil otherwise. func (cs *ConsensusState) enterPrecommit(height int64, round int) { + span := cs.addSpan("enterPrecommit") + defer span.End() + logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrecommit <= cs.Step) { @@ -1131,7 +1184,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { // the latest POLRound should be this round. polRound, _ := cs.Votes.POLInfo() if polRound < round { - panic(fmt.Sprintf("This POLRound should be %v but got %v", round, polRound)) + cs.panicWithTrace(span, fmt.Sprintf("This POLRound should be %v but got %v", round, polRound)) } // +2/3 prevoted nil. Unlock and precommit nil. @@ -1165,7 +1218,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { logger.Info("enterPrecommit: +2/3 prevoted proposal block. Locking", "hash", blockID.Hash) // Validate the block. if err := cs.state.ValidateBlock(cs.ProposalBlock); err != nil { - panic(fmt.Sprintf("enterPrecommit: +2/3 prevoted for an invalid block: %v", err)) + cs.panicWithTrace(span, fmt.Sprintf("enterPrecommit: +2/3 prevoted for an invalid block: %v", err)) } cs.LockedRound = round cs.LockedBlock = cs.ProposalBlock @@ -1192,6 +1245,9 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { // Enter: any +2/3 precommits for next round. func (cs *ConsensusState) enterPrecommitWait(height int64, round int) { + span := cs.addSpan("enterPrecommitWait") + defer span.End() + logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cs.TriggeredTimeoutPrecommit) { @@ -1203,7 +1259,7 @@ func (cs *ConsensusState) enterPrecommitWait(height int64, round int) { return } if !cs.Votes.Precommits(round).HasTwoThirdsAny() { - panic(fmt.Sprintf("enterPrecommitWait(%v/%v), but Precommits does not have any +2/3 votes", height, round)) + cs.panicWithTrace(span, fmt.Sprintf("enterPrecommitWait(%v/%v), but Precommits does not have any +2/3 votes", height, round)) } logger.Info(fmt.Sprintf("enterPrecommitWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) @@ -1220,6 +1276,9 @@ func (cs *ConsensusState) enterPrecommitWait(height int64, round int) { // Enter: +2/3 precommits for block func (cs *ConsensusState) enterCommit(height int64, commitRound int) { + span := cs.addSpan("enterCommit") + defer span.End() + logger := cs.Logger.With("height", height, "commitRound", commitRound) if cs.Height != height || cstypes.RoundStepCommit <= cs.Step { @@ -1242,7 +1301,7 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) { blockID, ok := cs.Votes.Precommits(commitRound).TwoThirdsMajority() if !ok { - panic("RunActionCommit() expects +2/3 precommits") + cs.panicWithTrace(span, "RunActionCommit() expects +2/3 precommits") } // The Locked* fields no longer matter. @@ -1272,15 +1331,18 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) { // If we have the block AND +2/3 commits for it, finalize. func (cs *ConsensusState) tryFinalizeCommit(height int64) { + span := cs.addSpan("tryFinalizeCommit") + defer span.End() + logger := cs.Logger.With("height", height) if cs.Height != height { - panic(fmt.Sprintf("tryFinalizeCommit() cs.Height: %v vs height: %v", cs.Height, height)) + cs.panicWithTrace(span, fmt.Sprintf("tryFinalizeCommit() cs.Height: %v vs height: %v", cs.Height, height)) } blockID, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() if !ok || len(blockID.Hash) == 0 { - logger.Error("Attempt to finalize failed. There was no +2/3 majority, or +2/3 was for .") + cs.logErrorWithTrace(span, "Attempt to finalize failed. There was no +2/3 majority, or +2/3 was for .") return } if !cs.ProposalBlock.HashesTo(blockID.Hash) { @@ -1296,6 +1358,9 @@ func (cs *ConsensusState) tryFinalizeCommit(height int64) { // Increment height and goto cstypes.RoundStepNewHeight func (cs *ConsensusState) finalizeCommit(height int64) { + span := cs.addSpan("finalizeCommit") + defer span.End() + if cs.Height != height || cs.Step != cstypes.RoundStepCommit { cs.Logger.Debug(fmt.Sprintf("finalizeCommit(%v): Invalid args. Current step: %v/%v/%v", height, cs.Height, cs.Round, cs.Step)) return @@ -1305,16 +1370,16 @@ func (cs *ConsensusState) finalizeCommit(height int64) { block, blockParts := cs.ProposalBlock, cs.ProposalBlockParts if !ok { - panic("Cannot finalizeCommit, commit does not have two thirds majority") + cs.panicWithTrace(span, "Cannot finalizeCommit, commit does not have two thirds majority") } if !blockParts.HasHeader(blockID.PartsHeader) { - panic("Expected ProposalBlockParts header to be commit header") + cs.panicWithTrace(span, "Expected ProposalBlockParts header to be commit header") } if !block.HashesTo(blockID.Hash) { - panic("Cannot finalizeCommit, ProposalBlock does not hash to commit hash") + cs.panicWithTrace(span, "Cannot finalizeCommit, ProposalBlock does not hash to commit hash") } if err := cs.state.ValidateBlock(block); err != nil { - panic(fmt.Sprintf("+2/3 committed an invalid block: %v", err)) + cs.panicWithTrace(span, fmt.Sprintf("+2/3 committed an invalid block: %v", err)) } cs.Logger.Info( @@ -1356,7 +1421,7 @@ func (cs *ConsensusState) finalizeCommit(height int64) { // restart). meta := walm.MetaMessage{Height: height + 1} if err := cs.wal.WriteMetaSync(meta); err != nil { // NOTE: fsync - panic(fmt.Sprintf("Failed to write %v msg to consensus wal due to %v. Check your FS and restart the node", meta, err)) + cs.panicWithTrace(span, fmt.Sprintf("Failed to write %v msg to consensus wal due to %v. Check your FS and restart the node", meta, err)) } fail.Fail() // XXX @@ -1369,10 +1434,10 @@ func (cs *ConsensusState) finalizeCommit(height int64) { var err error stateCopy, err = cs.blockExec.ApplyBlock(stateCopy, types.BlockID{Hash: block.Hash(), PartsHeader: blockParts.Header()}, block) if err != nil { - cs.Logger.Error("Error on ApplyBlock. Did the application crash? Please restart tendermint", "err", err) + cs.logErrorWithTrace(span, fmt.Sprintf("Error on ApplyBlock. Did the application crash? Please restart. Err: %v", err)) err := osm.Kill() if err != nil { - cs.Logger.Error("Failed to kill this process - please do so manually", "err", err) + cs.logErrorWithTrace(span, fmt.Sprintf("Failed to kill this process - please do so manually. Err: %v", err)) } return } @@ -1400,6 +1465,9 @@ func (cs *ConsensusState) finalizeCommit(height int64) { // ----------------------------------------------------------------------------- func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { + span := cs.addSpan("defaultSetProposal") + defer span.End() + // Already have one // TODO: possibly catch double proposals if cs.Proposal != nil { @@ -1445,6 +1513,12 @@ func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { // NOTE: block is not necessarily valid. // Asynchronously triggers either enterPrevote (before we timeout of propose) or tryFinalizeCommit, once we have the full block. func (cs *ConsensusState) addProposalBlockPart(msg *BlockPartMessage, peerID p2pTypes.ID) (added bool, err error) { + span := cs.addSpan("addProposalBlockPart") + span.SetAttributes( + attribute.String("peerID", peerID.String()), + ) + defer span.End() + height, round, part := msg.Height, msg.Round, msg.Part // Blocks might be reused, so round mismatch is OK @@ -1515,6 +1589,13 @@ func (cs *ConsensusState) addProposalBlockPart(msg *BlockPartMessage, peerID p2p // Attempt to add the vote. if its a duplicate signature, dupeout the validator func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerID p2pTypes.ID) (bool, error) { + span := cs.addSpan("tryAddVote") + span.SetAttributes( + attribute.Int("voteType", int(vote.Type)), + attribute.String("peerID", peerID.String()), + ) + defer span.End() + added, err := cs.addVote(vote, peerID) if err != nil { // If the vote height is off, we'll just ignore it, @@ -1548,6 +1629,13 @@ func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerID p2pTypes.ID) (bool // ----------------------------------------------------------------------------- func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2pTypes.ID) (added bool, err error) { + span := cs.addSpan("addVote") + span.SetAttributes( + attribute.Int("voteType", int(vote.Type)), + attribute.String("peerID", peerID.String()), + ) + defer span.End() + cs.Logger.Debug("addVote", "voteHeight", vote.Height, "voteType", vote.Type, "valIndex", vote.ValidatorIndex, "csHeight", cs.Height) // A precommit for the previous height? @@ -1694,13 +1782,16 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2pTypes.ID) (added b } default: - panic(fmt.Sprintf("Unexpected vote type %X", vote.Type)) // go-amino should prevent this. + cs.panicWithTrace(span, fmt.Sprintf("Unexpected vote type %X", vote.Type)) // go-amino should prevent this. } return added, err } func (cs *ConsensusState) signVote(type_ types.SignedMsgType, hash []byte, header types.PartSetHeader) (*types.Vote, error) { + span := cs.addSpan("signVote") + defer span.End() + // Flush the WAL. Otherwise, we may not recompute the same vote to sign, and the privValidator will refuse to sign anything. cs.wal.FlushAndSync() @@ -1741,6 +1832,9 @@ func (cs *ConsensusState) voteTime() time.Time { // sign the vote and publish on internalMsgQueue func (cs *ConsensusState) signAddVote(type_ types.SignedMsgType, hash []byte, header types.PartSetHeader) *types.Vote { + span := cs.addSpan("signAddVote") + defer span.End() + // if we don't have a key or we're not in the validator set, do nothing if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.GetPubKey().Address()) { return nil @@ -1763,8 +1857,9 @@ func (cs *ConsensusState) signAddVote(type_ types.SignedMsgType, hash []byte, he return vote } + // if !cs.replayMode { - cs.Logger.Error("Error signing vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err) + cs.logErrorWithTrace(span, fmt.Sprintf("Error signing vote: height: %v round: %v vote: %v err: %v", cs.Height, cs.Round, vote, err)) // } return nil } @@ -1793,6 +1888,47 @@ func (cs *ConsensusState) logTelemetry(block *types.Block) { metrics.BlockSizeBytes.Record(context.Background(), int64(block.Size())) } +func (cs *ConsensusState) logErrorWithTrace(span trace.Span, msg string) { + if span != nil { + span.RecordError(errors.New(msg)) + span.SetStatus(codes.Error, msg) + } + cs.Logger.Error(msg) +} + +func (cs *ConsensusState) panicWithTrace(span trace.Span, msg string) { + if span != nil { + span.RecordError(errors.New(msg)) + span.SetStatus(codes.Error, msg) + } + panic(msg) +} + +func (cs *ConsensusState) startRootSpan(height int64) trace.Span { + ctx, span := tracer().Start(context.Background(), fmt.Sprintf("NewHeight: %d", height)) + cs.traceCtx = ctx + return span +} + +func (cs *ConsensusState) addSpan(spanName string, opts ...trace.SpanStartOption) trace.Span { + step := fmt.Sprintf("%v", cs.Step) + + spanNameWithInfo := fmt.Sprintf("%s - %d/%s", spanName, cs.Round, step) + + ctx, span := tracer().Start(cs.traceCtx, spanNameWithInfo, opts...) + if span.IsRecording() { + span.SetAttributes( + attribute.Int64("csHeight", cs.Height), + attribute.Int("csRound", cs.Round), + attribute.String("csStep", step), + ) + } + + cs.traceCtx = ctx + + return span +} + // --------------------------------------------------------- func CompareHRS(h1 int64, r1 int, s1 cstypes.RoundStepType, h2 int64, r2 int, s2 cstypes.RoundStepType) int { diff --git a/tm2/pkg/telemetry/config/config.go b/tm2/pkg/telemetry/config/config.go index d11eba15016..ae1a47dee50 100644 --- a/tm2/pkg/telemetry/config/config.go +++ b/tm2/pkg/telemetry/config/config.go @@ -8,11 +8,14 @@ var errEndpointNotSet = errors.New("telemetry exporter endpoint not set") // Config is the configuration struct for the tm2 telemetry package type Config struct { - MetricsEnabled bool `json:"enabled" toml:"enabled"` + MetricsEnabled bool `json:"metrics_enabled" toml:"metrics_enabled"` MeterName string `json:"meter_name" toml:"meter_name"` ServiceName string `json:"service_name" toml:"service_name" comment:"in Prometheus this is transformed into the label 'exported_job'"` ServiceInstanceID string `json:"service_instance_id" toml:"service_instance_id" comment:"the ID helps to distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled service), in Prometheus this is transformed into the label 'exported_instance"` ExporterEndpoint string `json:"exporter_endpoint" toml:"exporter_endpoint" comment:"the endpoint to export metrics to, like a local OpenTelemetry collector"` + + TracesEnabled bool `json:"traces_enabled" toml:"traces_enabled"` + GracefulShutdownTelemetry bool `json:"graceful_shutdown_telemetry" toml:"graceful_shutdown_telemetry"` } // DefaultTelemetryConfig is the default configuration used for the node @@ -23,6 +26,9 @@ func DefaultTelemetryConfig() *Config { ServiceName: "tm2", ServiceInstanceID: "tm2-node-1", ExporterEndpoint: "", + + TracesEnabled: false, + GracefulShutdownTelemetry: false, } } diff --git a/tm2/pkg/telemetry/config/global.go b/tm2/pkg/telemetry/config/global.go new file mode 100644 index 00000000000..ed88074e24c --- /dev/null +++ b/tm2/pkg/telemetry/config/global.go @@ -0,0 +1,22 @@ +package config + +import ( + "sync/atomic" +) + +var ( + globalConfig Config + telemetryInitialized atomic.Bool +) + +func SetTelemetryInitialized() bool { + return telemetryInitialized.CompareAndSwap(false, true) +} + +func SetGlobalConfig(config Config) { + globalConfig = config +} + +func GetGlobalConfig() Config { + return globalConfig +} diff --git a/tm2/pkg/telemetry/init.go b/tm2/pkg/telemetry/init.go index d0b7a246e8a..0515410de40 100644 --- a/tm2/pkg/telemetry/init.go +++ b/tm2/pkg/telemetry/init.go @@ -5,41 +5,64 @@ package telemetry import ( "fmt" - "sync/atomic" + "log/slog" "github.com/gnolang/gno/tm2/pkg/telemetry/config" "github.com/gnolang/gno/tm2/pkg/telemetry/metrics" -) - -var ( - globalConfig config.Config - telemetryInitialized atomic.Bool + "github.com/gnolang/gno/tm2/pkg/telemetry/traces" + sdkMetric "go.opentelemetry.io/otel/sdk/metric" + sdkTrace "go.opentelemetry.io/otel/sdk/trace" ) // MetricsEnabled returns true if metrics have been initialized func MetricsEnabled() bool { - return globalConfig.MetricsEnabled + return config.GetGlobalConfig().MetricsEnabled +} + +// TracesEnabled returns true if traces have been initialized +func TracesEnabled() bool { + return config.GetGlobalConfig().TracesEnabled } // Init initializes the global telemetry -func Init(c config.Config) error { - // Check if the metrics are enabled at all - if !c.MetricsEnabled { - return nil +func Init(c config.Config, logger *slog.Logger) (*sdkTrace.TracerProvider, *sdkMetric.MeterProvider, error) { + anyTelemetryEnabled := c.MetricsEnabled || c.TracesEnabled + if !anyTelemetryEnabled { + return nil, nil, nil } // Validate the configuration if err := c.ValidateBasic(); err != nil { - return fmt.Errorf("unable to validate config, %w", err) + return nil, nil, fmt.Errorf("unable to validate config, %w", err) } // Check if it's been enabled already - if !telemetryInitialized.CompareAndSwap(false, true) { - return nil + if !config.SetTelemetryInitialized() { + return nil, nil, nil } // Update the global configuration - globalConfig = c + config.SetGlobalConfig(c) + + // Check if the metrics are enabled at all + var metricsProvider *sdkMetric.MeterProvider + var tracesProvider *sdkTrace.TracerProvider + var err error + if c.MetricsEnabled { + metricsProvider, err = metrics.Init(c) + if err != nil { + return nil, nil, fmt.Errorf("unable to initialize metrics, %w", err) + } + logger.Info("Metrics initialized") + } + + if c.TracesEnabled { + tracesProvider, err = traces.Init(c) + if err != nil { + return nil, nil, fmt.Errorf("unable to initialize traces, %w", err) + } + logger.Info("Traces initialized") + } - return metrics.Init(c) + return tracesProvider, metricsProvider, nil } diff --git a/tm2/pkg/telemetry/metrics/metrics.go b/tm2/pkg/telemetry/metrics/metrics.go index 5eeb664ec8f..2eddf4832e6 100644 --- a/tm2/pkg/telemetry/metrics/metrics.go +++ b/tm2/pkg/telemetry/metrics/metrics.go @@ -99,7 +99,7 @@ var ( WSRequestTime metric.Int64Histogram ) -func Init(config config.Config) error { +func Init(config config.Config) (*sdkMetric.MeterProvider, error) { var ( ctx = context.Background() exp sdkMetric.Exporter @@ -107,7 +107,7 @@ func Init(config config.Config) error { u, err := url.Parse(config.ExporterEndpoint) if err != nil { - return fmt.Errorf("error parsing exporter endpoint: %s, %w", config.ExporterEndpoint, err) + return nil, fmt.Errorf("error parsing exporter endpoint: %s, %w", config.ExporterEndpoint, err) } // Use oltp metric exporter with http/https or grpc @@ -118,7 +118,7 @@ func Init(config config.Config) error { otlpmetrichttp.WithEndpointURL(config.ExporterEndpoint), ) if err != nil { - return fmt.Errorf("unable to create http metrics exporter, %w", err) + return nil, fmt.Errorf("unable to create http metrics exporter, %w", err) } default: exp, err = otlpmetricgrpc.New( @@ -127,7 +127,7 @@ func Init(config config.Config) error { otlpmetricgrpc.WithInsecure(), ) if err != nil { - return fmt.Errorf("unable to create grpc metrics exporter, %w", err) + return nil, fmt.Errorf("unable to create grpc metrics exporter, %w", err) } } @@ -151,7 +151,7 @@ func Init(config config.Config) error { metric.WithDescription("block build duration"), metric.WithUnit("ms"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } // Networking // @@ -159,7 +159,7 @@ func Init(config config.Config) error { inboundPeersKey, metric.WithDescription("inbound peer count"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } // Initialize InboundPeers Gauge InboundPeers.Record(ctx, 0) @@ -168,7 +168,7 @@ func Init(config config.Config) error { outboundPeersKey, metric.WithDescription("outbound peer count"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } // Initialize OutboundPeers Gauge @@ -179,14 +179,14 @@ func Init(config config.Config) error { numMempoolTxsKey, metric.WithDescription("valid mempool transaction count"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if NumCachedTxs, err = meter.Int64Histogram( numCachedTxsKey, metric.WithDescription("cached mempool transaction count"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } // Runtime // @@ -194,21 +194,21 @@ func Init(config config.Config) error { vmExecMsgKey, metric.WithDescription("vm msg operation call frequency"), ); err != nil { - return fmt.Errorf("unable to create counter, %w", err) + return nil, fmt.Errorf("unable to create counter, %w", err) } if VMGasUsed, err = meter.Int64Histogram( vmGasUsedKey, metric.WithDescription("VM gas used"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if VMCPUCycles, err = meter.Int64Histogram( vmCPUCyclesKey, metric.WithDescription("VM CPU cycles"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } // Consensus // @@ -216,14 +216,14 @@ func Init(config config.Config) error { validatorCountKey, metric.WithDescription("size of the active validator set"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if ValidatorsVotingPower, err = meter.Int64Histogram( validatorVotingPowerKey, metric.WithDescription("total voting power of the active validator set"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if BlockInterval, err = meter.Int64Histogram( @@ -231,14 +231,14 @@ func Init(config config.Config) error { metric.WithDescription("interval between 2 subsequent blocks"), metric.WithUnit("s"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if BlockTxs, err = meter.Int64Histogram( blockTxsKey, metric.WithDescription("number of transactions within the latest block"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if BlockSizeBytes, err = meter.Int64Histogram( @@ -246,7 +246,7 @@ func Init(config config.Config) error { metric.WithDescription("size of the latest block in bytes"), metric.WithUnit("B"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if BlockGasPriceAmount, err = meter.Int64Histogram( @@ -254,7 +254,7 @@ func Init(config config.Config) error { metric.WithDescription("block gas price"), metric.WithUnit("token"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } // RPC // @@ -263,7 +263,7 @@ func Init(config config.Config) error { metric.WithDescription("http request response time"), metric.WithUnit("ms"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } if WSRequestTime, err = meter.Int64Histogram( @@ -271,8 +271,8 @@ func Init(config config.Config) error { metric.WithDescription("ws request response time"), metric.WithUnit("ms"), ); err != nil { - return fmt.Errorf("unable to create histogram, %w", err) + return nil, fmt.Errorf("unable to create histogram, %w", err) } - return nil + return provider, nil } diff --git a/tm2/pkg/telemetry/tracer.go b/tm2/pkg/telemetry/tracer.go new file mode 100644 index 00000000000..112da547f61 --- /dev/null +++ b/tm2/pkg/telemetry/tracer.go @@ -0,0 +1,28 @@ +package telemetry + +import ( + "sync" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" +) + +type TracerFactory func() trace.Tracer + +var noopTracerProvider = noop.NewTracerProvider() + +func Tracer(name string, options ...trace.TracerOption) TracerFactory { + var once sync.Once + var t trace.Tracer = noopTracerProvider.Tracer(name, options...) // Initilize noop tracer as default + return func() trace.Tracer { + if TracesEnabled() { + once.Do(func() { + provider := otel.GetTracerProvider() + t = provider.Tracer(name, options...) + }) + } + + return t + } +} diff --git a/tm2/pkg/telemetry/traces/traces.go b/tm2/pkg/telemetry/traces/traces.go new file mode 100644 index 00000000000..51fbf3560c1 --- /dev/null +++ b/tm2/pkg/telemetry/traces/traces.go @@ -0,0 +1,62 @@ +package traces + +import ( + "context" + "fmt" + "net/url" + + "github.com/gnolang/gno/tm2/pkg/telemetry/config" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" + "go.opentelemetry.io/otel/sdk/resource" + sdkTrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" +) + +func Init(cfg config.Config) (*sdkTrace.TracerProvider, error) { + var ( + ctx = context.Background() + exp sdkTrace.SpanExporter + ) + + u, err := url.Parse(cfg.ExporterEndpoint) + if err != nil { + return nil, fmt.Errorf("error parsing tracer exporter endpoint: %s, %w", cfg.ExporterEndpoint, err) + } + + // Use oltp metric exporter with http/https or grpc + switch u.Scheme { + case "http", "https": + exp, err = otlptracehttp.New( + ctx, + otlptracehttp.WithEndpointURL(cfg.ExporterEndpoint), + ) + if err != nil { + return nil, fmt.Errorf("unable to create http traces exporter, %w", err) + } + default: + exp, err = otlptracegrpc.New( + ctx, + otlptracegrpc.WithEndpoint(cfg.ExporterEndpoint), + otlptracegrpc.WithInsecure(), + ) + if err != nil { + return nil, fmt.Errorf("unable to create grpc traces exporter, %w", err) + } + } + + provider := sdkTrace.NewTracerProvider( + sdkTrace.WithBatcher(exp), + sdkTrace.WithResource(resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String(cfg.ServiceName), + semconv.ServiceVersionKey.String("1.0.0"), + semconv.ServiceInstanceIDKey.String(cfg.ServiceInstanceID), + )), + ) + + otel.SetTracerProvider(provider) + + return provider, nil +}