1 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊
Microsoft 曾經(jīng)支持一個(gè)名為BuildInfo.config
該文件的文件,該文件對(duì)這類事情很有用,但我認(rèn)為在 Visual Studio 2015 之后就放棄了對(duì)它的支持。
基本上,它是一個(gè)由 MSBuild 創(chuàng)建的簡單 XML 文件。當(dāng)與應(yīng)用程序二進(jìn)制文件一起部署時(shí),日志框架可以讀取文件并將詳細(xì)信息包含在日志輸出中。
您可以通過多種方式自己創(chuàng)建類似的功能。這就是我要做的...
創(chuàng)建一個(gè)空的構(gòu)建信息文件并將其與您的源代碼一起簽入。該文件只是一個(gè)參考示例——使用占位符數(shù)據(jù)。它可以是 XML、JSON 或任何其他格式(但應(yīng)該是基于文本的)。將文件的構(gòu)建操作設(shè)置為“內(nèi)容”,以便將其包含在構(gòu)建輸出中。
使用您的日志框架的模板或遙測(cè)初始化功能來讀取構(gòu)建信息文件并將其內(nèi)容包含在日志輸出中。確切的實(shí)現(xiàn)將取決于您的日志框架。
將 Powershell 腳本任務(wù)添加到 Azure DevOps 管道。該腳本應(yīng)該更新或覆蓋構(gòu)建信息文件。您可以從構(gòu)建變量中獲得一些好的信息。該任務(wù)應(yīng)在 MSBuild 編譯步驟之前運(yùn)行。
創(chuàng)建和解析 BuildInfo 文件
對(duì)于此示例,我將在文本文件中將構(gòu)建信息文件實(shí)現(xiàn)為簡單的鍵/值對(duì)。我選擇了簡單的文本,因?yàn)樗试S一個(gè)清晰的示例,而不需要任何第三方庫或復(fù)雜的解析。在您的應(yīng)用程序中,您可能希望使用 JSON、XML 或其他更標(biāo)準(zhǔn)化的東西。
首先,創(chuàng)建一個(gè)占位符構(gòu)建信息文件。該文件將在您的本地開發(fā)環(huán)境中使用,并將作為您的構(gòu)建信息架構(gòu)的參考。我打電話給 mine BuildInfo.txt
,并將其放在我項(xiàng)目的根目錄中。
COMMIT=commit not set BUILD=build not set
接下來,編寫一個(gè)幫助程序來解析構(gòu)建信息文件。我的很簡陋。添加一些針對(duì)丟失或格式錯(cuò)誤的構(gòu)建信息的防御措施是明智的,但我選擇省略任何防御性代碼以保持示例的重點(diǎn)。
class BuildInfo
{
// Singleton instance backing field
static readonly Lazy<BuildInfo> instance = new Lazy<BuildInfo>(() => new BuildInfo());
// Singleton instance public accessor
public static BuildInfo Instance => instance.Value;
public string Commit { get; }
public string Build { get; }
private BuildInfo()
{
// This is a very rudimentary example of parsing the info file. It
// will fail loudly on malformed input. Consider:
// 1) Using a standard file format (JSON, XML). I rolled my own
// here to avoid adding a dependency on a parsing library.
// 2) If you want your app to fail when no build info is
// available, add a more descriptive exception. If you don't
// want it to fail, add some devensive code or fallback logic.
var info = File.ReadAllLines("BuildInfo.txt")
.Select(l => l.Split('=', 2))
.ToDictionary(key => key[0], val => val[1]);
Commit = info["COMMIT"];
Build = info["BUILD"];
}
}
將構(gòu)建信息添加到您的日志輸出
我在這里使用 log4net,但是任何日志框架都應(yīng)該有一些類似的機(jī)制來自定義日志輸出。有關(guān)更多信息,請(qǐng)參閱框架的文檔。
首先,將您的構(gòu)建信息添加到日志記錄上下文中。這應(yīng)該在您的應(yīng)用程序的啟動(dòng)代碼中的某個(gè)位置 - 盡可能早。
log4net.GlobalContext.Properties["Build"] = BuildInfo.Instance.Build;
log4net.GlobalContext.Properties["Commit"] = BuildInfo.Instance.Commit;
然后,更新日志附加器的配置以包含自定義字段。這是控制臺(tái)附加程序的示例配置。重要的位是%property{BuildId}和%property{Commit}。
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<target value="Console.Error" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level [%property{BuildId}] [%property{Commit}] - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
現(xiàn)在,當(dāng)您調(diào)用 時(shí)log.Warn("Some log mesage"),您將看到以下控制臺(tái)輸出:
WARN [build not set] [commit not set] - Some log mesage
從 CI 獲取構(gòu)建詳細(xì)信息
最后,您需要從 CI 環(huán)境中獲取真正的構(gòu)建細(xì)節(jié)。我用一個(gè)非常簡單的 PowerShell 腳本任務(wù)做到了這一點(diǎn)。確保任務(wù)在構(gòu)建步驟之前運(yùn)行!
@(
"COMMIT=$($Env:BUILD_SOURCEVERSION)",
"BUILD=$($Env:BUILD_BUILDID)"
) | Out-File BuildInfo.txt
Get-ChildItem Env: | Sort Name(提示:您可以通過在 PowerShell 任務(wù)中運(yùn)行來查看所有可用的環(huán)境變量)
(另一個(gè)提示:如果您想使用 JSON 而不是文本,請(qǐng)查看ConvertTo-Jsoncmdlet)
現(xiàn)在,如果所有部分都到位,CI 服務(wù)器應(yīng)該覆蓋簽入的構(gòu)建信息文件。然后,新文件應(yīng)與您的可部署工件打包在一起,并復(fù)制到您的服務(wù)器。啟動(dòng)時(shí),您的應(yīng)用程序應(yīng)讀取構(gòu)建信息,然后該信息應(yīng)包含在每條日志消息中。
在你的構(gòu)建和部署過程之間有很多小事情要安排好,所以要為一些試驗(yàn)和錯(cuò)誤做好準(zhǔn)備。根據(jù)我的經(jīng)驗(yàn),CI/CD 設(shè)置往往很乏味。
- 1 回答
- 0 關(guān)注
- 111 瀏覽
添加回答
舉報(bào)