public static async void Run( [QueueTrigger( "chef-statsd", Connection = "AzureWebJobsStorage") ] string rawmetric, [Table("settings")] CloudTable settingTable, ILogger log) { // Instantiate objects to get relevant data from the configuration store IEntity config = new Config(); DataService ds = new DataService(settingTable, config); // Get all the settings for the CentralLogging partition Configs config_store = await ds.GetAll(Constants.ConfigStorePartitionKey); Configs central_logging = await ds.GetAll("central_logging"); // Create an instance of the LogAnalyticsWriter LogAnalyticsWriter log_analytics_writer = new LogAnalyticsWriter(log, config_store, central_logging); // Create a datetime variable that is the Linux Epoch time System.DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0); // Parse the raw metric json into an object Newtonsoft.Json.Linq.JObject statsd = Newtonsoft.Json.Linq.JObject.Parse(rawmetric); // Iterate around the series data and create a message for each one var metrics = (JArray)statsd["series"]; foreach (JObject metric in metrics) { // create message to send to Log Analytics ChefMetricMessage message = new ChefMetricMessage(); // determine the time of the event DateTime time = dateTime.AddSeconds((double)metric["points"][0][0]); // set the properties of the object message.metricName = (string)metric["metric"]; message.metricType = (string)metric["type"]; message.metricHost = (string)metric["host"]; message.time = time; message.metricValue = (double)metric["points"][0][1]; message.customerName = config_store.customer_name; message.subscriptionId = config_store.subscription_id; // Submit the metric to Log Analytics log_analytics_writer.Submit(message, "statsd_log"); } }
public static async Task Process(CloudTable settingTable, ILogger log) { // Create necessary objects to get information from the datastore IEntity config = new Config(); // Get all the settings for the CentralLogging partition DataService ds = new DataService(settingTable, config); Configs config_store = await ds.GetAll(Constants.ConfigStorePartitionKey); Configs central_logging = await ds.GetAll("central_logging"); // Create an instance of the LogAnalyticsWriter LogAnalyticsWriter log_analytics_writer = new LogAnalyticsWriter(log, config_store, central_logging); // Get the Automate token and fqdn from the config store string token_setting = config_store.logging_automate_token; string fqdn_setting = config_store.automate_fqdn; // Set the time that that count was performed DateTime time = DateTime.UtcNow; // Request the NodeCount data from the Automate Server NodeCount node_count = await GetData("node", config_store.logging_automate_token, config_store.automate_fqdn, log); node_count.time = time; node_count.subscriptionId = config_store.subscription_id; node_count.customerName = config_store.customer_name; // Submit the node count log_analytics_writer.Submit(node_count, "ChefAutomateAMAInfraNodeCount"); // Request the UserCount data from the Automate Server UserCount user_count = await GetData("user", config_store.logging_automate_token, config_store.automate_fqdn, log); user_count.time = time; user_count.subscriptionId = config_store.subscription_id; user_count.customerName = config_store.customer_name; log_analytics_writer.Submit(user_count, "ChefAutomateAMAUserCount"); }
public async Task <HttpResponseMessage> Process(HttpRequest req, CloudTable table, ILogger logger, string category, Microsoft.Azure.WebJobs.ExecutionContext executionContext) { // Initialise variables HttpResponseMessage response = null; ResponseMessage msg = new ResponseMessage(); StringBuilder db = new StringBuilder(); _logger = logger; // The StarterKit will only response to GET requests if (req.Method == "GET") { logger.LogInformation("StarterKit has been requested"); // Create a config object to pass to the dataservice Config config = new Config(Constants.ConfigStorePartitionKey); // Create a data service object to get all the data DataService ds = new DataService(table, config); string clientKeyFilename = string.Empty; string validatorKeyFilename = string.Empty; // Define the paths for the structure and then ensure they exist chefRepoPath = Path.Combine(executionContext.FunctionDirectory, "chef-repo"); extrasPath = Path.Combine(chefRepoPath, "extras"); dotChefPath = Path.Combine(chefRepoPath, ".chef"); string keyFilename = string.Empty; string keyPath = string.Empty; string key = string.Empty; // Delete the repo path if it already exists // This is to prevent old files from being added to the zip that has been requseted if (Directory.Exists(chefRepoPath)) { logger.LogInformation("Deleting existing path: {0}", chefRepoPath); Directory.Delete(chefRepoPath, true); } // Create the directories again if (!Directory.Exists(extrasPath)) { logger.LogInformation("Creating directory: {0}", extrasPath); Directory.CreateDirectory(extrasPath); } if (!Directory.Exists(dotChefPath)) { logger.LogInformation("Creating directory: {0}", dotChefPath); Directory.CreateDirectory(dotChefPath); } // Get all the configuration items from the config store config_store = await ds.GetAll(category); config_store.DeriveServerURLs(); // Write out the org and user keys WriteKey("org"); WriteKey("user"); // Patche the necessary templates // Create the template compiler Mustache.FormatCompiler compiler = new Mustache.FormatCompiler(); // Build up a dictionary of the files to be rendered and the base path to use Dictionary <string, string> templates = new Dictionary <string, string>(); templates.Add("credentials.txt", chefRepoPath); templates.Add("chef_extension.json", extrasPath); templates.Add("knife.rb", dotChefPath); string path; string data; Mustache.Generator generator; foreach (KeyValuePair <string, string> entry in templates) { path = Path.Combine(executionContext.FunctionAppDirectory, "templates", entry.Key); generator = compiler.Compile(File.ReadAllText(path)); data = generator.Render(config_store); File.WriteAllText(Path.Combine(entry.Value, entry.Key), data); } // Create a json file of the config_store as this can be read by other languages if need be path = Path.Combine(extrasPath, "credentials.json"); data = JsonConvert.SerializeObject(config_store, Formatting.Indented); File.WriteAllText(path, data); // Determine the path for the zip file string zipPath = Path.Combine(executionContext.FunctionDirectory, "starter_kit.zip"); // Remove the file if it already exists if (File.Exists(zipPath)) { File.Delete(zipPath); } // Create the zip file from the chef repo directory ZipFile.CreateFromDirectory(chefRepoPath, zipPath); response = msg.CreateResponse(zipPath); // delete the zip file and the chefrepo Directory.Delete(chefRepoPath, true); File.Delete(zipPath); } else { msg.SetError("HTTP Method not supported", true, HttpStatusCode.BadRequest); response = msg.CreateResponse(); } return(response); }
/// <summary> /// Method to process the request that has come into the API /// </summary> /// <param name="req">Request object</param> /// <param name="table">Table object on which operations will be performed</param> /// <param name="log">Logger interface</param> /// <param name="identifier">Identifier passed into the API</param> /// <param name="category">Category passed into the request</param> /// <returns>HttpResponseMessage to return to the client</returns> public async Task <HttpResponseMessage> Process(HttpRequest req, CloudTable table, ILogger log, string identifier, string category) { // Initialise variables HttpResponseMessage response = null; ResponseMessage msg = new ResponseMessage(); // Create a dataservice object to use DataService ds = new DataService(table, this); // Using the method of the request determine if retrieving or upserting an item switch (req.Method) { case "GET": dynamic result; // attempt to get the data based on whether the identifier is set or not if (String.IsNullOrEmpty(identifier)) { log.LogInformation("All configs have been requested from the '{0}' category", category); // no identifier has been supplied so retrieve all records result = await ds.GetAll(category); } else { log.LogInformation("Configuration item has been requested from the '{0}' category: {1}", category, identifier); result = await ds.Get(identifier, category); } // get the response from the datservice and setup the response for the client // check that the result is not null, if it is then set the response accordlingly msg = ds.GetResponseMessage(); if (result == null) { // set the properties on the message object msg.SetError(String.Format("Item cannot be found: {0}", identifier), true, HttpStatusCode.NotFound); response = msg.CreateResponse(); } else { response = msg.CreateResponse(result); } break; case "POST": case "PUT": // get the json data from the request string json = await new StreamReader(req.Body).ReadToEndAsync(); // parse the json Parse(json); // Determine if there are any errors msg = GetResponseMessage(); if (msg.IsError()) { response = msg.CreateResponse(); } else { // attempt to insert the data bool status = await ds.Insert(); } break; case "DELETE": // attempt to remove the item from the data store result = await ds.Delete(identifier, category); msg = ds.GetResponseMessage(); response = msg.CreateResponse(); break; } // Return the response return(response); }
public async Task <HttpResponseMessage> Process(HttpRequest req, CloudTable table, ILogger log, string category) { HttpResponseMessage msg; // Only respond to an HTTP Post if (req.Method == "POST") { // Create dataservice to access data in the config table Config config = new Config(); DataService ds = new DataService(table, config); // Get all the settings for the CentralLogging partition Configs config_store = await ds.GetAll(category); Configs central_logging = await ds.GetAll("centralLogging"); // Get the body of the request string body = await new StreamReader(req.Body).ReadToEndAsync(); string[] logs = body.Split('}'); // Create an instance of the LogAnalyticsWriter LogAnalyticsWriter log_analytics_writer = new LogAnalyticsWriter(log, config_store, central_logging); // Create an instance of AutomateLog which will hold the data that has been submitted AutomateLog data = new AutomateLog(); // iterate around each item in the logs string appended_item; string log_name; foreach (string item in logs) { appended_item = item; if (!appended_item.EndsWith("}")) { appended_item += "}"; } // output the item to the console log.LogInformation(item); // if the item is not empty, process it if (!string.IsNullOrEmpty(item)) { // Deserialise the item into the AutomateLog object data = JsonConvert.DeserializeObject <AutomateLog>(appended_item as string); // From this data create an AutomateMessage object AutomateMessage automate_message = AutomateLogParser.ParseGenericLogMessage(data.MESSAGE_s, config_store.customer_name, config_store.subscription_id, log); // if the message is known then submit to LogAnalytics if (automate_message.sourcePackage.ToLower() != "uknown entry") { // Determine the log name of the message log_name = automate_message.sourcePackage.Replace("-", "") + "log"; // Submit the data log_analytics_writer.Submit(automate_message, log_name); } } } _response.SetMessage("Log data accepted"); msg = _response.CreateResponse(); } else { _response.SetError("HTTP Method not supported", true, HttpStatusCode.BadRequest); msg = _response.CreateResponse(); } return(msg); }