diff --git a/src/Agoda.Builds.Metrics/BuildTimeData.cs b/src/Agoda.Builds.Metrics/BuildTimeData.cs new file mode 100644 index 0000000..94900a4 --- /dev/null +++ b/src/Agoda.Builds.Metrics/BuildTimeData.cs @@ -0,0 +1,74 @@ +using System; +using System.Text.Json.Serialization; + +namespace Agoda.Builds.Metrics +{ + public class BuildTimeData + { + [JsonPropertyName("id")] + public Guid Id { get; set; } + + [JsonPropertyName("metricsVersion")] + public string MetricsVersion { get; set; } + + [JsonPropertyName("userName")] + public string UserName { get; set; } + + [JsonPropertyName("cpuCount")] + public int CpuCount { get; set; } + + [JsonPropertyName("hostname")] + public string Hostname { get; set; } + + [JsonPropertyName("platform")] + public PlatformID Platform { get; set; } + + [JsonPropertyName("os")] + public string Os { get; set; } + + [JsonPropertyName("timeTaken")] + public string TimeTaken { get; set; } + + [JsonPropertyName("branch")] + public string Branch { get; set; } + + [JsonPropertyName("type")] + public string Type { get; set; } + + [JsonPropertyName("projectName")] + public string ProjectName { get; set; } + + [JsonPropertyName("repository")] + public string Repository { get; set; } + + [JsonPropertyName("repositoryName")] + public string RepositoryName { get; set; } + + [JsonPropertyName("date")] + public DateTime Date { get; set; } + + public BuildTimeData( + string metricsVersion, + string type, + string projectName, + string timeTaken, + GitContext gitContext + ) + { + Id = Guid.NewGuid(); + Type = type; + MetricsVersion = metricsVersion; + UserName = Environment.UserName; + CpuCount = Environment.ProcessorCount; + Hostname = Environment.MachineName; + Platform = Environment.OSVersion.Platform; + Os = Environment.OSVersion.VersionString; + ProjectName = projectName; + TimeTaken = timeTaken; + Repository = gitContext.RepositoryUrl; + RepositoryName = gitContext.RepositoryName; + Branch = gitContext.BranchName; + Date = DateTime.UtcNow; + } + } +} diff --git a/src/Agoda.Builds.Metrics/BuildTimePublisher.cs b/src/Agoda.Builds.Metrics/BuildTimePublisher.cs new file mode 100644 index 0000000..78e6c1b --- /dev/null +++ b/src/Agoda.Builds.Metrics/BuildTimePublisher.cs @@ -0,0 +1,33 @@ +using System; +using System.Net.Http; +using System.Text; +using System.Text.Json; + +namespace Agoda.Builds.Metrics +{ + internal static class BuildTimePublisher + { + public static void Publish(string apiEndpoint, BuildTimeData result) + { + using (var httpClient = new HttpClient()) + { + httpClient.Timeout = TimeSpan.FromSeconds(10); + + var content = new StringContent(JsonSerializer.Serialize(result), Encoding.UTF8, "application/json"); + var response = httpClient.PostAsync(GetApiEndpoint(apiEndpoint), content).Result; + + response.EnsureSuccessStatusCode(); + } + } + + static string GetApiEndpoint(string apiEndpoint) + { + if (string.IsNullOrEmpty(apiEndpoint)) + { + apiEndpoint = Environment.GetEnvironmentVariable("BUILD_METRICS_ES_ENDPOINT"); + } + + return string.IsNullOrEmpty(apiEndpoint) ? "http://compilation-metrics/dotnet" : apiEndpoint; + } + } +} diff --git a/src/Agoda.Builds.Metrics/GitContext.cs b/src/Agoda.Builds.Metrics/GitContext.cs new file mode 100644 index 0000000..4140ba8 --- /dev/null +++ b/src/Agoda.Builds.Metrics/GitContext.cs @@ -0,0 +1,9 @@ +namespace Agoda.Builds.Metrics +{ + public class GitContext + { + public string RepositoryUrl { get; set; } + public string RepositoryName { get; set; } + public string BranchName { get; set; } + } +} diff --git a/src/Agoda.Builds.Metrics/GitContextReader.cs b/src/Agoda.Builds.Metrics/GitContextReader.cs new file mode 100644 index 0000000..77c6201 --- /dev/null +++ b/src/Agoda.Builds.Metrics/GitContextReader.cs @@ -0,0 +1,52 @@ +using System; +using System.Diagnostics; + +namespace Agoda.Builds.Metrics +{ + public static class GitContextReader + { + public static GitContext GetGitContext() + { + string url = RunCommand("config --get remote.origin.url"); + string branch = RunCommand("rev-parse --abbrev-ref HEAD"); + + return new GitContext + { + RepositoryUrl = url, + RepositoryName = GetRepositoryNameFromUrl(url), + BranchName = branch + }; + } + + static string RunCommand(string args) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + ( + fileName: Environment.OSVersion.Platform == PlatformID.Win32NT ? "git.exe" : "git" + ) + { + UseShellExecute = false, + WorkingDirectory = Environment.CurrentDirectory, + RedirectStandardInput = true, + RedirectStandardOutput = true, + Arguments = args + } + }; + + process.Start(); + + return process.StandardOutput.ReadLine(); + } + + static string GetRepositoryNameFromUrl(string url) + { + var repositoryName = url.Substring(url.LastIndexOf('/') + 1); + + return repositoryName.EndsWith(".git") + ? repositoryName.Substring(0, repositoryName.LastIndexOf('.')) + : repositoryName; + } + } +} diff --git a/src/Agoda.Builds.Metrics/MeasureBuildTime.cs b/src/Agoda.Builds.Metrics/MeasureBuildTime.cs index 48ad34f..a3ae5ed 100644 --- a/src/Agoda.Builds.Metrics/MeasureBuildTime.cs +++ b/src/Agoda.Builds.Metrics/MeasureBuildTime.cs @@ -1,101 +1,62 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Net.Http; -using System.Text; -using Microsoft.Build.Framework; +using Microsoft.Build.Framework; using Microsoft.Build.Utilities; +using System; -using System.Text.Json; namespace Agoda.Builds.Metrics { public class MeasureBuildTime : Task { + /// + /// Set by the 'CaptureBuildTime' build event. + /// + public string ProjectName { get; set; } + + /// + /// Set by the 'CaptureBuildTime' build event. + /// public string StartDateTime { get; set; } + + /// + /// Set by the 'CaptureBuildTime' build event. + /// public string EndDateTime { get; set; } + + /// + /// Seems not to be set from anywhere. + /// public string ApiEndPoint { get; set; } - public string ProjectName { get; set; } + + /// + /// Set by the Task.Execute method. + /// Used by the 'CaptureBuildTime' build event. + /// [Output] - public string DebugOutput { get; set; } + public string BuildTimeMilliseconds { get; set; } public override bool Execute() { - DebugOutput = (DateTime.Parse(EndDateTime) - DateTime.Parse(StartDateTime)).TotalMilliseconds.ToString(); + BuildTimeMilliseconds = DateTime.Parse(EndDateTime).Subtract(DateTime.Parse(StartDateTime)).TotalMilliseconds.ToString(); + try { - var gitUrl = GetGitDetails("config --get remote.origin.url"); - var data = new - { - id = Guid.NewGuid(), - metricsVersion = typeof(MeasureBuildTime).Assembly.GetName().Version.ToString(), - userName = Environment.UserName, - cpuCount = Environment.ProcessorCount, - hostname = Environment.MachineName, - platform = Environment.OSVersion.Platform, - os = Environment.OSVersion.VersionString, - timeTaken = DebugOutput, - branch = GetGitDetails("rev-parse --abbrev-ref HEAD"), - type = ".Net", - projectName = ProjectName, - repository = gitUrl, - repositoryName = extractRepositoryName(gitUrl), - date = DateTime.UtcNow - }; + var gitContext = GitContextReader.GetGitContext(); - using (var httpClient = new HttpClient()) - { - httpClient.Timeout = TimeSpan.FromMinutes(1); - PopulateBuildMetricESDetails(); - var content = new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json"); - var responses = httpClient.PostAsync(ApiEndPoint, content).Result; - if (!responses.IsSuccessStatusCode) - { - Log.LogMessage($"Unable to publish metrics - {responses.ReasonPhrase}"); - } - } + var result = new BuildTimeData( + metricsVersion: typeof(MeasureBuildTime).Assembly.GetName().Version.ToString(), + type: ".Net", + projectName: ProjectName, + timeTaken: BuildTimeMilliseconds, + gitContext: gitContext + ); + BuildTimePublisher.Publish(ApiEndPoint, result); } catch (Exception ex) { - Log.LogMessage($"Unexpected issue while generating metrics - {ex.Message}"); + Log.LogMessage("An error occured while capturing the build time: " + ex); } return true; } - - private static string extractRepositoryName(string gitUrl) - { - var repositoryName = gitUrl.Substring(gitUrl.LastIndexOf('/') + 1); - return repositoryName.EndsWith(".git") ? repositoryName.Substring(0, repositoryName.LastIndexOf('.')) : repositoryName; - } - - private void PopulateBuildMetricESDetails() - { - if (string.IsNullOrEmpty(ApiEndPoint)) - { - ApiEndPoint = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_METRICS_ES_ENDPOINT")) ? Environment.GetEnvironmentVariable("BUILD_METRICS_ES_ENDPOINT") : "http://compilation-metrics/dotnet"; - } - } - - private static string GetGitDetails(string arg) - { - string executableName = "git"; - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - executableName += ".exe"; - ProcessStartInfo startInfo = new ProcessStartInfo(executableName); - - startInfo.UseShellExecute = false; - startInfo.WorkingDirectory = Environment.CurrentDirectory; - startInfo.RedirectStandardInput = true; - startInfo.RedirectStandardOutput = true; - startInfo.Arguments = arg; - - Process process = new Process(); - process.StartInfo = startInfo; - process.Start(); - - var gitBranch = process.StandardOutput.ReadLine(); - return gitBranch; - } } } diff --git a/src/Agoda.Builds.Metrics/build/Agoda.Builds.Metrics.targets b/src/Agoda.Builds.Metrics/build/Agoda.Builds.Metrics.targets index 2168eaa..1263087 100644 --- a/src/Agoda.Builds.Metrics/build/Agoda.Builds.Metrics.targets +++ b/src/Agoda.Builds.Metrics/build/Agoda.Builds.Metrics.targets @@ -8,23 +8,19 @@ - - - + + + - + - + StartDateTime="$(StartTime)" + EndDateTime="$([System.DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss.ffffzzz"))"> + - +