コード例 #1
0
        static void Main()
        {
            var server = new BlackboxMetricServer(10000);

            server.Start();


            server.AddScrapeCallback((metricFactory, queryString) =>
            {
                var counter = metricFactory.CreateCounter("example_random", "Just a random value", "xyz");

                counter.IncTo(new Random().NextDouble());
                counter.WithLabels("value1").IncTo(new Random().NextDouble());
            });

            Console.Read();
        }
コード例 #2
0
        static internal BlackboxMetricServer Start()
        {
            Log.Main.Info("start metric server");
            var metricServer = new BlackboxMetricServer(Program.Configuration.Global.Port, Program.Configuration.Global.MetricsUrl);

            metricServer.Start();

            metricServer.AddScrapeCallback(async(cancel, factory, queryStrings) =>
            {
                var requestId = Interlocked.Increment(ref requestCounter);

                bool showLogOutput    = false;
                Log.LogLevel?logLevel = null;
                bool invalidLogLevel  = false;
                string logLevelStr    = queryStrings["debug"];

                if (logLevelStr != null)
                {
                    showLogOutput = true;

                    if (Enum.TryParse(typeof(Log.LogLevel), logLevelStr, out object logLevelObj))
                    {
                        logLevel = (Log.LogLevel)logLevelObj;
                    }
                    else
                    {
                        invalidLogLevel = true;
                    }
                }

                var log = Log.Main.CreateContext($"request {requestId}", logLevel, showLogOutput);
                if (invalidLogLevel)
                {
                    log.Error($"invalid log level '{logLevelStr}' set");
                }

                // create a reference to the currently loaded configuration, to avoid changes during a scrape
                var localConfiguration = Program.Configuration;

                log.Debug1("start scrape");

                try
                {
                    var target = queryStrings["target"];

                    if (target == null)
                    {
                        throw new ScrapeFailedException("target missing");
                    }

                    if (!localConfiguration.Targets.TryGetValue(target, out var targetConfiguration))
                    {
                        throw new ScrapeFailedException($"target '{target}' not found");
                    }

                    string username = targetConfiguration.Username ?? localConfiguration.Global.Username;
                    string password = targetConfiguration.Password ?? localConfiguration.Global.Password;

                    var connection = ConnectionManager.GetConnection(log, targetConfiguration.Host, username, password);

                    string[] moduleNames;

                    // either use modules listed in query string or the modules listed in target
                    var queryModule = queryStrings["module"];
                    if (queryModule != null)
                    {
                        moduleNames = queryModule.Split(",");
                    }
                    else
                    {
                        moduleNames = targetConfiguration.Modules;
                    }

                    await Task.WhenAll(moduleNames.Select((moduleName) =>
                    {
                        if (!localConfiguration.Modules.TryGetValue(moduleName, out var module))
                        {
                            throw new ScrapeFailedException($"module '{moduleName}' not found");
                        }

                        var moduleLogger = log.CreateContext($"module {moduleName}");

                        if (targetConfiguration.ModuleExtensions.TryGetValue(moduleName, out var moduleExtension))
                        {
                            moduleLogger.Debug1("target has module extension");

                            module = module.DeepClone();
                            moduleExtension.TryExtendModule(log.CreateContext("target extension"), module);
                        }

                        var tasks    = new List <Task>();
                        var iCommand = 1;
                        foreach (var moduleCommand in module)
                        {
                            var commandLogger = moduleLogger.CreateContext($"command {iCommand++}");
                            var namePrefix    = localConfiguration.Global.Prefix + '_' + (moduleCommand.Prefix ?? moduleName) + '_';


                            var metricCollectorsCache = new Dictionary <Configuration.ModuleCommand, MetricCollector[]>();
                            moduleCommand.Prepare(commandLogger, factory, namePrefix, metricCollectorsCache);

                            tasks.Add(moduleCommand.Run(commandLogger, connection.TikConnection, factory, localConfiguration, namePrefix, targetConfiguration.Variables, metricCollectorsCache));
                        }

                        return(Task.WhenAll(tasks));
                    })).ConfigureAwait(false);

                    connection.LastUse = DateTime.Now;
                }
                catch (Exception ex)
                {
                    log.Error(ex.ToString());
                    if (!showLogOutput)
                    {
                        throw;
                    }
                }
                finally
                {
                    log.Debug1("end scrape");
                }

                return(showLogOutput ? string.Join("\r\n", log.Logs) : null);
            });

            return(metricServer);
        }
コード例 #3
0
        static void Main(string[] args)
        {
            try
            {
                bool showHelp = false;

                OptionSet optionSet = new OptionSet {
                    { "c|config=", "path to the yml configuration", c => configurationFile = Path.GetFullPath(c) },
                    { "v", "enable verbose output", v => { if (v != null)
                                                           {
                                                               Log.Main.Level = Log.LogLevel.Debug1;
                                                           }
                      } },
                    { "vv", "enable more verbose output", v => { if (v != null)
                                                                 {
                                                                     Log.Main.Level = Log.LogLevel.Debug2;
                                                                 }
                      } },
                    { "h|help", "show this help", h => showHelp = h != null }
                };

                optionSet.Parse(args);

                Console.WriteLine($"MikrotikExporter.Net {Assembly.GetExecutingAssembly().GetName().Version}");

                if (showHelp)
                {
                    optionSet.WriteOptionDescriptions(Console.Out);
                    return;
                }

                if (string.IsNullOrWhiteSpace(configurationFile))
                {
                    Log.Main.Error("configuration file missing. use --help for more information.");
                    return;
                }

                // inital configuration load
                if (!ConfigurationManager.Load(Log.Main.CreateContext("configuration load initial")))
                {
                    return;
                }

                if (!string.IsNullOrEmpty(Configuration.Global.ReloadUrl))
                {
                    backgroundTasks.Add(ReloadServer.Start(cts.Token));
                }

                if (!string.IsNullOrEmpty(Configuration.Global.DiscoverUrl))
                {
                    backgroundTasks.Add(DiscoverServer.Start(cts.Token));
                }

                // start the cleanup for stale connections
                ConnectionManager.InitCleanup(cts.Token);
                ConfigurationManager.InitReload(cts.Token);

                metricServer = MetricServer.Start();

                var tcsRun = new TaskCompletionSource <object>();

                Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
                {
                    Log.Main.Info("stopping...");
                    tcsRun.SetResult(null);
                    e.Cancel = true;
                };

                tcsRun.Task.ContinueWith((action) =>
                {
                    cts.Cancel();
                    Log.Main.Info("stop metric server");
                    backgroundTasks.Add(metricServer.StopAsync());
                    return(Task.WhenAll(backgroundTasks));
                }, TaskScheduler.Current).Wait();
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                Log.Main.Error($"unexpected error: {ex}");
            }
        }