Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ public static class Constants
public const string ContinuousPath = "continuous";
public const string TriggeredPath = "triggered";

public const string DummyRazorExtension = ".kudu777";
public const string DummyRazorExtension = ".kudu777";

public const string ScmDeploymentKind = "ScmDeploymentKind";

// Kudu trace text file related
public const string DeploymentTracePath = LogFilesPath + @"/kudu/deployment";
Expand Down
3 changes: 3 additions & 0 deletions Kudu.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ private static int Main(string[] args)
log4net.Config.XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
}

// signify the deployment is done by git push
System.Environment.SetEnvironmentVariable(Constants.ScmDeploymentKind, "GitPush");

// Turn flag on in app.config to wait for debugger on launch
if (ConfigurationManager.AppSettings["WaitForDebuggerOnStart"] == "true")
{
Expand Down
3 changes: 3 additions & 0 deletions Kudu.Core/Deployment/DeploymentManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ private void MarkStatusComplete(IDeploymentStatusFile status, bool success)

// Cleaup old deployments
PurgeAndGetDeployments();

// Report deployment completion
DeploymentCompletedInfo.Persist(_environment.RequestId, status, _analytics);
}

// since the expensive part (reading all files) is done,
Expand Down
71 changes: 71 additions & 0 deletions Kudu.Core/Helpers/DeploymentCompletedInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.IO;
using Kudu.Core.Deployment;
using Kudu.Core.Infrastructure;
using Kudu.Core.Tracing;
using Newtonsoft.Json;

namespace Kudu.Core.Helpers
{
public class DeploymentCompletedInfo
{
public const string LatestDeploymentFile = "LatestDeployment.json";

public string TimeStamp { get; set; }
public string SiteName { get; set; }
public string RequestId { get; set; }
public string Kind { get; set; }
public string Status { get; set; }
public string Details { get; set; }

private static IAnalytics _analytics;

public static void Persist(string requestId, IDeploymentStatusFile status, IAnalytics analytics)
{
// signify the deployment is done by git push
var kind = System.Environment.GetEnvironmentVariable(Constants.ScmDeploymentKind);
if (string.IsNullOrEmpty(kind))
{
kind = status.Deployer;
}
_analytics = analytics;
var serializedStatus = JsonConvert.SerializeObject(status, Formatting.Indented);
Persist(status.SiteName, kind, requestId, status.Status.ToString(), serializedStatus);
}

public static void Persist(string siteName, string kind, string requestId, string status, string details)
{
var info = new DeploymentCompletedInfo
{
TimeStamp = $"{DateTime.UtcNow:s}Z",
SiteName = siteName,
Kind = kind,
RequestId = requestId,
Status = status,
Details = details ?? string.Empty
};

try
{
var path = Path.Combine(System.Environment.ExpandEnvironmentVariables(@"%HOME%"), "site", "deployments");
var file = Path.Combine(path, $"{Constants.LatestDeployment}.json");
var content = JsonConvert.SerializeObject(info, Formatting.Indented);
FileSystemHelpers.EnsureDirectory(path);

// write deployment info to %home%\site\deployments\LatestDeployment.json
OperationManager.Attempt(() => FileSystemHelpers.Instance.File.WriteAllText(file, content));

_analytics.DeploymentCompleted(
info.SiteName,
info.Kind,
info.RequestId,
info.Status,
info.Details);
}
catch (Exception ex)
{
_analytics.UnexpectedException(ex);
}
}
}
}
21 changes: 21 additions & 0 deletions Kudu.Core/Helpers/PostDeploymentHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,27 @@ private static IEnumerable<string> GetPostBuildActionScripts()
|| f.EndsWith(".bat", StringComparison.OrdinalIgnoreCase)
|| f.EndsWith(".ps1", StringComparison.OrdinalIgnoreCase))
.OrderBy(n => n);
}

/// <summary>
/// This common codes is to invoke post deployment operations.
/// It is written to require least dependencies but framework assemblies.
/// Caller is responsible for synchronization.
/// </summary>
/// <param name="siteName">WEBSITE_SITE_NAME env</param>
/// <param name="kind">MSDeploy, ZipDeploy, Git, ..</param>
/// <param name="requestId">for correlation</param>
/// <param name="status">Success or fail</param>
/// <param name="details">deployment specific json</param>
/// <param name="tracer">tracing</param>
public static async Task InvokeWithDetails(string kind, string requestId, string status, string details, TraceListener tracer)
{
DeploymentCompletedInfo.Persist(System.Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"), kind, requestId, status, details);

if (string.Equals("Success", status, StringComparison.OrdinalIgnoreCase))
{
await Invoke(requestId, tracer);
}
}

private static void Trace(TraceEventType eventType, string message)
Expand Down
2 changes: 2 additions & 0 deletions Kudu.Core/Tracing/IAnalytics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ public interface IAnalytics
void DeprecatedApiUsed(string route, string userAgent, string method, string path);

void SiteExtensionEvent(string method, string path, string result, string deploymentDurationInMilliseconds, string Message);

void DeploymentCompleted(string siteName, string kind, string requestId, string status, string details);
}
}
2 changes: 2 additions & 0 deletions Kudu.Core/Tracing/KuduEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public class KuduEvent
public string verb = string.Empty;
public int statusCode = 0;
public long latencyInMilliseconds = 0;
public string deploymentDetails = string.Empty;
public string deploymentStatus = string.Empty;

public override string ToString()
{
Expand Down
1 change: 1 addition & 0 deletions Kudu.Core/Tracing/KuduEventGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public static IKuduEventGenerator Log(ISystemEnvironment systemEnvironment = nul
}
else
{
// Log4Net logger output to a file when running on Linux
_eventGenerator = new Log4NetEventGenerator();
}
}
Expand Down
18 changes: 18 additions & 0 deletions Kudu.Core/Tracing/KuduEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ public void GenericEvent(string siteName, string Message, string requestId, stri
}
}

/// <summary>
/// DeploymentCompleted event
/// </summary>
/// <param name="siteName">WEBSITE_SITE_NAME</param>
/// <param name="kind">MSDeploy, ZipDeploy, Git, ...</param>
/// <param name="requestId">requestId</param>
/// <param name="status">Success, Failed</param>
/// <param name="details">deployment-specific json</param>
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters")]
[Event(65516, Level = EventLevel.Informational, Message = "Deployment completed for site {0}", Channel = EventChannel.Operational)]
public void DeploymentCompleted(string siteName, string kind, string requestId, string status, string details)
{
if (IsEnabled())
{
WriteEvent(65516, siteName, kind, requestId, status, details);
}
}

[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters")]
[Event(65515, Level = EventLevel.Informational, Message = "Api event for site {0}", Channel = EventChannel.Operational)]
public void ApiEvent(string siteName, string Message, string address, string verb, string requestId, int statusCode, long latencyInMilliseconds, string userAgent)
Expand Down
13 changes: 13 additions & 0 deletions Kudu.Core/Tracing/LinuxContainerEventGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ public void ProjectDeployed(string siteName, string projectType, string result,
LogKuduTraceEvent(kuduEvent);
}

public void DeploymentCompleted(string siteName, string kind, string requestId, string status, string details)
{
KuduEvent kuduEvent = new KuduEvent
{
siteName = siteName,
deploymentDetails = details,
deploymentStatus = status,
requestId = requestId,
};

LogKuduTraceEvent(kuduEvent);
}

public void WebJobStarted(string siteName, string jobName, string scriptExtension, string jobType, string siteMode, string error, string trigger)
{
KuduEvent kuduEvent = new KuduEvent
Expand Down
13 changes: 13 additions & 0 deletions Kudu.Core/Tracing/Log4NetEventGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ public void ProjectDeployed(string siteName, string projectType, string result,
LogKuduTraceEvent(kuduEvent);
}

public void DeploymentCompleted(string siteName, string kind, string requestId, string status, string details)
{
KuduEvent kuduEvent = new KuduEvent
{
siteName = siteName,
deploymentDetails = details,
deploymentStatus = status,
requestId = requestId,
};

LogKuduTraceEvent(kuduEvent);
}

public void WebJobStarted(string siteName, string jobName, string scriptExtension, string jobType, string siteMode, string error, string trigger)
{
KuduEvent kuduEvent = new KuduEvent
Expand Down
3 changes: 0 additions & 3 deletions Kudu.Services/Deployment/DeploymentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Kudu.Contracts.Infrastructure;
using Kudu.Contracts.Settings;
Expand All @@ -27,7 +25,6 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
using Kudu.Services.Zip;
using System.IO.Compression;

namespace Kudu.Services.Deployment
Expand Down
10 changes: 6 additions & 4 deletions Kudu.Services/Deployment/PushDeploymentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ namespace Kudu.Services.Deployment
{
public class PushDeploymentController : Controller
{
private const string DefaultDeployer = "Push-Deployer";
private const string ZipDeploy = "ZipDeploy";
private const string ZipDeployUrl = "ZipDeploy-via-url";
private const string WarDeploy = "WarDeploy";
private const string DefaultMessage = "Created via a push deployment";

private readonly IEnvironment _environment;
Expand Down Expand Up @@ -64,7 +66,7 @@ public async Task<IActionResult> ZipPushDeploy(
[FromQuery] bool overwriteWebsiteRunFromPackage = false,
[FromQuery] string author = null,
[FromQuery] string authorEmail = null,
[FromQuery] string deployer = DefaultDeployer,
[FromQuery] string deployer = ZipDeploy,
[FromQuery] string message = DefaultMessage)
{
using (_tracer.Step("ZipPushDeploy"))
Expand Down Expand Up @@ -117,7 +119,7 @@ public async Task<IActionResult> ZipPushDeployViaUrl(
[FromQuery] bool overwriteWebsiteRunFromPackage = false,
[FromQuery] string author = null,
[FromQuery] string authorEmail = null,
[FromQuery] string deployer = DefaultDeployer,
[FromQuery] string deployer = ZipDeployUrl,
[FromQuery] string message = DefaultMessage)
{
using (_tracer.Step("ZipPushDeployViaUrl"))
Expand Down Expand Up @@ -158,7 +160,7 @@ public async Task<IActionResult> WarPushDeploy(
[FromQuery] bool isAsync = false,
[FromQuery] string author = null,
[FromQuery] string authorEmail = null,
[FromQuery] string deployer = DefaultDeployer,
[FromQuery] string deployer = WarDeploy,
[FromQuery] string message = DefaultMessage)
{
using (_tracer.Step("WarPushDeploy"))
Expand Down