DataConnectors/AzureStorage/LogDownloader.cs (77 lines of code) (raw):

using Microsoft.Azure.Storage; using Microsoft.Azure.Storage.Blob; using System; using System.Collections.Generic; using System.Text; // https://blogs.msdn.microsoft.com/windowsazurestorage/2011/08/02/windows-azure-storage-logging-using-logs-to-track-storage-requests/ namespace HoneyBucketLogParser { class LogDownloader { private const string LogStartTime = "StartTime"; private const string LogEndTime = "EndTime"; public static List<CloudBlob> DownloadStorageLogs(string connectionString, string serviceName, DateTime startTimeOfSearch, DateTime endTimeOfSearch) { var account = CloudStorageAccount.Parse(connectionString); var blobClient = account.CreateCloudBlobClient(); return ListLogFiles(blobClient, serviceName, startTimeOfSearch.ToUniversalTime(), endTimeOfSearch.ToUniversalTime()); } /// <summary> /// Given service name, start time for search and end time for search, creates a prefix that can be used /// to efficiently get a list of logs that may match the search criteria /// </summary> /// <param name="service"></param> /// <param name="startTime"></param> /// <param name="endTime"></param> /// <returns></returns> private static string GetSearchPrefix(string service, DateTime startTime, DateTime endTime) { StringBuilder prefix = new StringBuilder("$logs/"); prefix.AppendFormat("{0}/", service); // if year is same then add the year if (startTime.Year == endTime.Year) { prefix.AppendFormat("{0}/", startTime.Year); } else { return prefix.ToString(); } // if month is same then add the month if (startTime.Month == endTime.Month) { prefix.AppendFormat("{0:D2}/", startTime.Month); } else { return prefix.ToString(); } // if day is same then add the day if (startTime.Day == endTime.Day) { prefix.AppendFormat("{0:D2}/", startTime.Day); } else { return prefix.ToString(); } // if hour is same then add the hour if (startTime.Hour == endTime.Hour) { prefix.AppendFormat("log-{0:D2}00", startTime.Hour); } return prefix.ToString(); } /// <summary> /// Given a service, start time, end time, provide list of log files /// </summary> /// <param name="blobClient"></param> /// <param name="serviceName">The name of the service interested in</param> /// <param name="startTimeForSearch">Start time for the search</param> /// <param name="endTimeForSearch">End time for the search</param> /// <returns></returns> private static List<CloudBlob> ListLogFiles(CloudBlobClient blobClient, string serviceName, DateTime startTimeForSearch, DateTime endTimeForSearch) { List<CloudBlob> selectedLogs = new List<CloudBlob>(); // form the prefix to search. Based on the common parts in start and end time, this prefix is formed string prefix = GetSearchPrefix(serviceName, startTimeForSearch, endTimeForSearch); // List the blobs using the prefix IEnumerable<IListBlobItem> blobs = blobClient.ListBlobs( prefix, true, BlobListingDetails.Metadata); // iterate through each blob and figure the start and end times in the metadata foreach (IListBlobItem item in blobs) { CloudBlob log = item as CloudBlob; if (log != null) { // we will exclude the file if the file does not have log entries in the interested time range. DateTime startTime = DateTime.Parse(log.Metadata[LogStartTime]).ToUniversalTime(); DateTime endTime = DateTime.Parse(log.Metadata[LogEndTime]).ToUniversalTime(); bool exclude = (startTime > endTimeForSearch || endTime < startTimeForSearch); if (!exclude) { selectedLogs.Add(log); } } } return selectedLogs; } } }