Skip to content

Commit

Permalink
refactor code for reusability (#21)
Browse files Browse the repository at this point in the history
Co-authored-by: nic <[email protected]>
  • Loading branch information
nic-agoda and nic authored Dec 19, 2022
1 parent ab15013 commit 218895b
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 87 deletions.
74 changes: 74 additions & 0 deletions src/Agoda.Builds.Metrics/BuildTimeData.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
33 changes: 33 additions & 0 deletions src/Agoda.Builds.Metrics/BuildTimePublisher.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
9 changes: 9 additions & 0 deletions src/Agoda.Builds.Metrics/GitContext.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
52 changes: 52 additions & 0 deletions src/Agoda.Builds.Metrics/GitContextReader.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
111 changes: 36 additions & 75 deletions src/Agoda.Builds.Metrics/MeasureBuildTime.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Set by the 'CaptureBuildTime' build event.
/// </summary>
public string ProjectName { get; set; }

/// <summary>
/// Set by the 'CaptureBuildTime' build event.
/// </summary>
public string StartDateTime { get; set; }

/// <summary>
/// Set by the 'CaptureBuildTime' build event.
/// </summary>
public string EndDateTime { get; set; }

/// <summary>
/// Seems not to be set from anywhere.
/// </summary>
public string ApiEndPoint { get; set; }
public string ProjectName { get; set; }

/// <summary>
/// Set by the Task.Execute method.
/// Used by the 'CaptureBuildTime' build event.
/// </summary>
[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;
}
}
}
20 changes: 8 additions & 12 deletions src/Agoda.Builds.Metrics/build/Agoda.Builds.Metrics.targets
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,19 @@

<UsingTask TaskName="Agoda.Builds.Metrics.MeasureBuildTime" AssemblyFile="$(TaskAssembly)" />

<Target Name="SaveTheTime" BeforeTargets="PreBuildEvent">
<CreateProperty
Value="$([System.DateTime]::Now.ToString(&quot;yyyy-MM-dd HH:mm:ss.ffffzzz&quot;))">
<Output
TaskParameter="Value"
PropertyName="StartTime" />
<Target Name="SetStartTime" BeforeTargets="PreBuildEvent">
<CreateProperty Value="$([System.DateTime]::Now.ToString(&quot;yyyy-MM-dd HH:mm:ss.ffffzzz&quot;))">
<Output TaskParameter="Value" PropertyName="StartTime" />
</CreateProperty>
</Target>

<Target Name="ExecuteMeasurement" BeforeTargets="PostBuildEvent">
<Target Name="CaptureBuildTime" BeforeTargets="PostBuildEvent">
<Agoda.Builds.Metrics.MeasureBuildTime
StartDateTime="$(StartTime)"
EndDateTime="$([System.DateTime]::Now.ToString(&quot;yyyy-MM-dd HH:mm:ss.ffffzzz&quot;))"
ProjectName="$(MSBuildProjectName)"
>
<Output PropertyName="BuildTime" TaskParameter="DebugOutput" />
StartDateTime="$(StartTime)"
EndDateTime="$([System.DateTime]::Now.ToString(&quot;yyyy-MM-dd HH:mm:ss.ffffzzz&quot;))">
<Output PropertyName="BuildTime" TaskParameter="BuildTimeMilliseconds" />
</Agoda.Builds.Metrics.MeasureBuildTime>
<Message Text="The Build Time was $(BuildTime) ms" Importance="High" />
<Message Text="The measured build time for $(ProjectName) was $(BuildTime)ms." Importance="High" />
</Target>
</Project>

0 comments on commit 218895b

Please sign in to comment.