Esempio n. 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();
        }
Esempio n. 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);
        }