Category: traceability

Open Tracing instrumentation for running process

Open tracing allows you to trace calls between (micro)services . It has also calls for HTTP and Sql. For a ASP.NET Core application the code is at follows ( for exporting at Jaeger, for example):


services.AddOpenTelemetryTracing(b =>
{
string nameAssemblyEntry = Assembly.GetEntryAssembly().GetName().Name;
var rb = ResourceBuilder.CreateDefault();
rb.AddService(nameAssemblyEntry);
var data = new Dictionary<string, object>() {
{ "PC", Environment.MachineName } };
data.Add("Exe", nameAssemblyEntry);
rb.AddAttributes(data);
_ = b
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSqlClientInstrumentation()
.AddSource("MySource")
.SetResourceBuilder(rb)
.AddJaegerExporter(c =>
{
var s = Configuration.GetSection("Jaeger");

s.Bind(c);

});


})
;

This code was made with

 <PackageReference Include=”OpenTelemetry” Version=”1.1.0-beta1″ />
<PackageReference Include=”OpenTelemetry.Instrumentation.AspNetCore” Version=”1.0.0-rc3″ />
<PackageReference Include=”OpenTelemetry.Exporter.Jaeger” Version=”1.1.0-beta1″ />
<PackageReference Include=”OpenTelemetry.Extensions.Hosting” Version=”1.0.0-rc3″ />
<PackageReference Include=”OpenTelemetry.Instrumentation.Http” Version=”1.0.0-rc3″ />
<PackageReference Include=”OpenTelemetry.Instrumentation.SqlClient” Version=”1.0.0-rc3″ />

For a .NET Core console, the code is :

string nameAssemblyEntry = Assembly.GetEntryAssembly().GetName().Name;
var rb = ResourceBuilder.CreateDefault();
rb.AddService(nameAssemblyEntry);
var data = new Dictionary<string, object>() {
{ "PC", Environment.MachineName } };
data.Add("Exe", nameAssemblyEntry);
rb.AddAttributes(data);

openTelemetry = Sdk.CreateTracerProviderBuilder()
.AddSource("MySource")
.AddHttpClientInstrumentation()
.AddSqlClientInstrumentation()
.SetResourceBuilder(rb)
.AddJaegerExporter(o =>
 {
 var s = config.GetSection("Jaeger");
 s.Bind(o);
                   })
.Build();

But how to transmit data for a Web that calls a process and not modify the command line ? Simple : via environment variable

The code for running the process is :

var pi = new ProcessStartInfo();
pi.FileName = ...;
pi.WorkingDirectory = ...;

var act = Activity.Current;
if (act != null)
{
 pi.EnvironmentVariables.Add(nameof(act.TraceId), act.TraceId.ToHexString());
 pi.EnvironmentVariables.Add(nameof(act.SpanId), act.SpanId.ToHexString());
}
var p = Process.Start(pi);

For the console, the code is:

 using (var act = MyActivitySource.StartActivity("StartProcess", ActivityKind.Producer))
            {
                act.SetTag("proc", "main");
               
                var traceStr = (Environment.GetEnvironmentVariable(nameof(act.TraceId)));
                if (!string.IsNullOrWhiteSpace(traceStr))
                {
                    var trace = ActivityTraceId.CreateFromString(traceStr);
                    var span = ActivitySpanId.CreateFromString(Environment.GetEnvironmentVariable(nameof(act.SpanId)));
                    act.SetParentId(trace, span, ActivityTraceFlags.Recorded);
                }

                try
                {
                    //executing code
                    act.SetStatus(Status.Ok);
                }
                catch (Exception ex)
                {
                    act.SetStatus(Status.Error);
                    throw;
                }
                
            }  

Traceability – conclusion – part 7 of 7

Those were previous posts:

Traceability in .NET – 1 of 7

Traceability in .NET–1.0.*–part 2 of 7

Tracebility in .NET -source control – part 3 of 7

Traceability in .NET–.tt files–add build date– part 4 of 7

Traceability in .NET–.tt files–add changeset – part 5 of 7

.TT – add more informations(.NET version , build ) – part 6 of 7

As conclusions:
You can put 1.0.* and Visual Studio will take care about incrementing the version- but it will be difficult to identify the build date.
Or you can use Team Foundation Server to put dates into the version
Or you can use .TT files – in simple or advanced way – and make automatically the version

The source code is at https://traceabilitydemo.codeplex.com/

The entire video you can find at http://www.youtube.com/playlist?list=PL4aSKgR4yk4M3BgSjQvryEFjwq_sGUgh7

The entire written series is here: http://msprogrammer.serviciipeweb.ro/wp-content/uploads/traceability.pdf

.TT – add more informations(.NET version , build ) – part 6 of 7

As you can see from the previous chapter, we have added to the AssemblyDescription more informations – like .NET version, build configuration , and more

You can see those with an explorer add-on http://www.codeproject.com/Articles/118909/Windows-7-File-properties-Version-Tab-Shell-Extens

Video : http://youtu.be/A_qSdVV93qk

Demo project here : https://traceabilitydemo.codeplex.com/releases/view/132231

Source code here : https://traceabilitydemo.codeplex.com/SourceControl/changeset/view/110446

Traceability in .NET–.tt files–add changeset – part 5 of 7

We wish to add , from the .tt file , the id of the last TFS checkin. For this purpose we will connect to TFS and we will investigate in the current project the latest change.

We will use the facility of .tt file to connect to the host and ask for various features ( such as TFS )

The .tt file code is:

  

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name="EnvDTE80" #>


<#@ assembly name="Microsoft.VisualStudio.TeamFoundation.VersionControl" #>
<#@ assembly name="Microsoft.TeamFoundation.Client"#>
<#@ assembly name="Microsoft.TeamFoundation.Common"#>
<#@ assembly name="Microsoft.TeamFoundation"#>
<#@ assembly name="Microsoft.TeamFoundation.WorkItemTracking.Client"#>
<#@ assembly name="Microsoft.TeamFoundation.VersionControl.Client"#>
<#@ assembly name="Microsoft.TeamFoundation.ProjectManagement"#>


<#@ import namespace="Microsoft.TeamFoundation.Client"#>
<#@ import namespace="Microsoft.TeamFoundation.VersionControl.Client"#>


<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE80" #>
<#@ output extension=".cs" #>
<#
DTE dte=null;
var serviceProvider = Host as IServiceProvider;
    if (serviceProvider != null) {
        dte = serviceProvider.GetService(typeof(DTE)) as DTE;
    }
	if (dte == null) {
        throw new Exception("generate build number can only execute through the Visual Studio IDE");
		}
ProjectItem projectItem = dte.Solution.FindProjectItem(Host.TemplateFile);
int netVersion=0;

var proj=projectItem.ContainingProject;
var configmgr = proj.ConfigurationManager;
var config = configmgr.ActiveConfiguration;
string regex=@"^.+?Version=v(?<version>\-?\d+\.\d+).*?$";
var options = RegexOptions.Multiline;
string input= proj.Properties.Item("TargetFrameworkMoniker").Value.ToString();
	
MatchCollection matches = Regex.Matches(input,regex,options);
foreach (Match match in matches)
{
		
    netVersion = (int)(double.Parse(match.Groups["version"].Value)*100);
		
}


string filePath = proj.FullName;
string dirPath = System.IO.Path.GetDirectoryName(filePath);
var wsInfo = Microsoft.TeamFoundation.VersionControl.Client.Workstation.Current.GetLocalWorkspaceInfo(filePath );
 
 // Get the TeamProjectCollection and VersionControl server associated with the
 // WorkspaceInfo
 var tpc = new TfsTeamProjectCollection(wsInfo.ServerUri);
 var vcServer = tpc.GetService<VersionControlServer>();
 
 // Now get the actual Workspace OM object
 var ws = vcServer.GetWorkspace(wsInfo);
 
 // We are interested in the current version of the workspace
 var versionSpec = VersionSpec.Latest;
 
 var historyParams = new QueryHistoryParameters(dirPath, RecursionType.Full);
 historyParams.ItemVersion = versionSpec;
 historyParams.VersionEnd = versionSpec;
 historyParams.MaxResults = 1;
 
 var changeset = vcServer.QueryHistory(historyParams).FirstOrDefault();


 var dt = DateTime.Now;
var userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
userName = userName.Split('\\').Last();

 #>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BuildTraceabilityDemo")]
//http://www.codeproject.com/Articles/118909/Windows-7-File-properties-Version-Tab-Shell-Extens
[assembly: AssemblyDescription("BuildDate,<#=dt.ToString("yyyyMMdd_HHmmss")#>\r\n<#=proj.Properties.Item("TargetFrameworkMoniker").Value.ToString()#>\r\nBuild by,<#=userName#>\r\nConfig,<#=config.ConfigurationName#>,\r\nChangeset,<#=changeset.ChangesetId#>")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BuildTraceabilityDemo")]
[assembly: AssemblyCopyright("Copyright ©  <#= dt.Year#>")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("75ff7863-cb83-4d9b-80de-4a0de2781918")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.<#=dt.Year#>.<#=dt.Month#>.<#=dt.Day#>")]


   

Video : http://youtu.be/A_qSdVV93qk

Demo project here : https://traceabilitydemo.codeplex.com/releases/view/132231

Source code here : https://traceabilitydemo.codeplex.com/SourceControl/changeset/view/110446

Traceability in .NET–.tt files–add build date– part 4 of 7

Firstly we propose that build can automatically put the data in AssemblyVersion. For this you will need somehow to generate the current date.

We can do this in several ways – for example, a post build event. We will use a .tt file that will automatically generate this date. We will use for other things – for example, last checkin of TFS.

Running .tt files can be done either via command Build => Transform all T4 templates or in a before build event solution here . The solution is taken from http://stackoverflow.com/questions/1646580/get-visual-studio-to-run-a-t4-template-on-every-build – run in pre-build event the .tt file.

You can download demo project from here: https://traceabilitydemo.codeplex.com/releases/view/132229

Source code: https://traceabilitydemo.codeplex.com/SourceControl/changeset/view/110438

Video : https://www.youtube.com/watch?v=lZJ1NCIDejU

Next time we will add the TFS checkin id

Tracebility in .NET -source control – part 3 of 7

Adding version with Source Control

This depends on what source control do you use . We will not discuss this in details – it is enough to searchAssemblyVersion. For TFS or SVN you can use https://github.com/loresoft/msbuildtasks : TfsVersion si SvnVersion

You can use command line too : http://www.woodwardweb.com/vsts/determining_the.html

Full tutorial with powershell you can find at http://blogs.msdn.com/b/visualstudioalm/archive/2013/07/24/basic-tfbuild-scripts.aspx http://msdn.microsoft.com/en-us/library/dn376353.aspx#env_vars http://curah.microsoft.com/8047/run-scripts-in-your-team-foundation-build-process

I have made a video at : https://www.youtube.com/watch?v=teiSgEYZXog

I can send source code –it is on visualstudio.com

Traceability in .NET–1.0.*–part 2 of 7

Traceability in NET

Each project in Visual Studio contains a file named AssemblyInfo.cs that contains summary information about the component. We will discuss these lines:

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

As seen the traceability already exists in .NET .The difference between AssemblyVersion and AssemblyFileVersion is detailed here: http://support.microsoft.com/kb/556041

What we want to achieve is that after a change of the source code and recompile, the AssemblyVersion (or AssemblyFileVersion) to show us how we can "recover" source code

It is obvious that if we change the source code will remain all AssemblyVersion 1.0.0.0.

So if we want to have control over versions then we can modify the version manually .

In the following tutorials we will show various ways to automatically change the version, as well as to add other details in AssemblyDescription.

Official Way (1.0. *)

The easiest way is to put

[assembly: AssemblyVersion("1.0.*")]

In AssemblyInfo.cs and comment

//[assembly: AssemblyFileVersion("1.0.0.0")]

In this way, the version will increment every time.

The code on AssemblyInfo.cs will look as following:

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
// [assembly: AssemblyVersion("1.0.0.0")]
//[assembly: AssemblyFileVersion("1.0.0.0")]


Video: https://www.youtube.com/watch?v=jq6Uu64md1s

You can download the demo project here: http://traceabilitydemo.codeplex.com/releases/view/130512

The source code you can download from here:
https://traceabilitydemo.codeplex.com/SourceControl/changeset/view/110330

What is disturbing is not incremented so that we can see, for example, build on site.

Next time we will make same increment from Source control( TFS)

Traceability in .NET – 1 of 7

What is traceability?

From Wikipedia, http://en.wikipedia.org/wiki/Traceability :
Traceability is the ability to verify the history, location, or application of an item by means of documented recorded identification.
We define traceability in software tracking capabilities and implementation of software components to know exactly:
1 The date the component was done (so that we can reproduce the source code)
2 Details of the production (version frameworks, other components, compilation debug / release, other data) so as to have the ability to distinguish between different versions
Assume that we have already answered yes to step 1 (Do you use source control?) from http://www.joelonsoftware.com/articles/fog0000000043.html
Also (although we do not use;)) is good to study and Semantic Version http://semver.org/

Why we need traceability in software

Suppose we have a source code that you distribute one to several customers. Suppose we modify the code for version two. Some of his old clients make software upgrades – others not. If a customer reports a bug, how do we know which version of the source code had problems?

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.