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;
}
}
}