Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a very basic prometheus exporter #2143

Merged
merged 8 commits into from
Jul 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion OpenTelemetry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "exception-reporting", "docs
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "customizing-the-sdk", "docs\trace\customizing-the-sdk\customizing-the-sdk.csproj", "{64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "getting-started", "docs\metrics\getting-started\getting-started.csproj", "{DFB0AD2F-11BE-4BCD-A77B-1018C3344FA8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started", "docs\metrics\getting-started\getting-started.csproj", "{DFB0AD2F-11BE-4BCD-A77B-1018C3344FA8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Exporter.Prometheus", "src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj", "{52158A12-E7EF-45A1-859F-06F9B17410CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -412,6 +414,10 @@ Global
{DFB0AD2F-11BE-4BCD-A77B-1018C3344FA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DFB0AD2F-11BE-4BCD-A77B-1018C3344FA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DFB0AD2F-11BE-4BCD-A77B-1018C3344FA8}.Release|Any CPU.Build.0 = Release|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
1 change: 1 addition & 0 deletions examples/Console/Examples.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Zipkin\OpenTelemetry.Exporter.Zipkin.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Jaeger\OpenTelemetry.Exporter.Jaeger.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.InMemory\OpenTelemetry.Exporter.InMemory.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj" />
</ItemGroup>
</Project>
7 changes: 2 additions & 5 deletions examples/Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static void Main(string[] args)
.MapResult(
(JaegerOptions options) => TestJaegerExporter.Run(options.Host, options.Port),
(ZipkinOptions options) => TestZipkinExporter.Run(options.Uri),
(PrometheusOptions options) => TestPrometheusExporter.Run(options.Port, options.PushIntervalInSecs, options.DurationInMins),
(PrometheusOptions options) => TestPrometheusExporter.Run(options.Port, options.DurationInMins),
(MetricsOptions options) => TestMetrics.Run(options),
(GrpcNetClientOptions options) => TestGrpcNetClient.Run(),
(HttpClientOptions options) => TestHttpClient.Run(),
Expand Down Expand Up @@ -83,13 +83,10 @@ internal class ZipkinOptions
[Verb("prometheus", HelpText = "Specify the options required to test Prometheus")]
internal class PrometheusOptions
{
[Option('i', "pushIntervalInSecs", Default = 15, HelpText = "The interval at which Push controller pushes metrics.", Required = false)]
public int PushIntervalInSecs { get; set; }

[Option('p', "port", Default = 9184, HelpText = "The port to expose metrics. The endpoint will be http://localhost:port/metrics (This is the port from which your Prometheus server scraps metrics from.)", Required = false)]
public int Port { get; set; }

[Option('d', "duration", Default = 2, HelpText = "Total duration in minutes to run the demo. Run atleast for a min to see metrics flowing.", Required = false)]
[Option('d', "duration", Default = 2, HelpText = "Total duration in minutes to run the demo.", Required = false)]
public int DurationInMins { get; set; }
}

Expand Down
42 changes: 37 additions & 5 deletions examples/Console/TestPrometheusExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Threading;
using System.Threading.Tasks;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;

namespace Examples.Console
{
internal class TestPrometheusExporter
{
internal static object Run(int port, int pushIntervalInSecs, int totalDurationInMins)
{
System.Console.WriteLine($"OpenTelemetry Prometheus Exporter is making metrics available at http://localhost:{port}/metrics/");
private static readonly Meter MyMeter = new Meter("TestMeter", "0.0.1");
private static readonly Counter<long> Counter = MyMeter.CreateCounter<long>("counter");

internal static object Run(int port, int totalDurationInMins)
{
/*
Following is sample prometheus.yml config. Adjust port,interval as needed.

Expand All @@ -42,9 +46,37 @@ internal static object Run(int port, int pushIntervalInSecs, int totalDurationIn
static_configs:
- targets: ['localhost:9184']
*/
System.Console.WriteLine("Press Enter key to exit.");
System.Console.ReadLine();
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddSource("TestMeter")
.AddPrometheusExporter(opt => opt.Url = $"http://localhost:{port}/metrics/")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the simplicity here. User is not expected to anything about temporality (delta vs cumulative)!. Hope it can stay that way..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable, because Prometheus is always cumulative right? I guess the only thing that would change this is if Prometheus introduced support for delta aggregations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea.. Views will likely make this more complex :)

.Build();

using var token = new CancellationTokenSource();
Task writeMetricTask = new Task(() =>
{
while (!token.IsCancellationRequested)
{
Counter.Add(
10,
new KeyValuePair<string, object>("tag1", "value1"),
new KeyValuePair<string, object>("tag2", "value2"));

Counter.Add(
100,
new KeyValuePair<string, object>("tag1", "anothervalue"),
new KeyValuePair<string, object>("tag2", "somethingelse"));
Task.Delay(10).Wait();
}
});
writeMetricTask.Start();

token.CancelAfter(totalDurationInMins * 60 * 1000);

System.Console.WriteLine($"OpenTelemetry Prometheus Exporter is making metrics available at http://localhost:{port}/metrics/");
System.Console.WriteLine($"Press Enter key to exit now or will exit automatically after {totalDurationInMins} minutes.");
System.Console.ReadLine();
token.Cancel();
System.Console.WriteLine("Exiting...");
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// <copyright file="PrometheusExporterEventSource.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System;
using System.Diagnostics.Tracing;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Exporter.Prometheus.Implementation
{
/// <summary>
/// EventSource events emitted from the project.
/// </summary>
[EventSource(Name = "OpenTelemetry-Exporter-Prometheus")]
internal class PrometheusExporterEventSource : EventSource
{
public static PrometheusExporterEventSource Log = new PrometheusExporterEventSource();

[NonEvent]
public void FailedExport(Exception ex)
{
if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1)))
{
this.FailedExport(ex.ToInvariantString());
}
}

[NonEvent]
public void FailedShutdown(Exception ex)
{
if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1)))
{
this.FailedShutdown(ex.ToInvariantString());
}
}

[NonEvent]
public void CanceledExport(Exception ex)
{
if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1)))
{
this.CanceledExport(ex.ToInvariantString());
}
}

[Event(1, Message = "Failed to export metrics: '{0}'", Level = EventLevel.Error)]
public void FailedExport(string exception)
{
this.WriteEvent(1, exception);
}

[Event(2, Message = "Canceled to export metrics: '{0}'", Level = EventLevel.Error)]
public void CanceledExport(string exception)
{
this.WriteEvent(2, exception);
}

[Event(3, Message = "Failed to shutdown Metrics server '{0}'", Level = EventLevel.Error)]
public void FailedShutdown(string exception)
{
this.WriteEvent(3, exception);
}
}
}
Loading