Azure ApplicationInsights track custom metrics using the TelemetryClient

The Microsoft.ApplicationInsights nuget package is your code gateway to the Microsoft Application Insights portal, and also to the Azure Monitor universe. You use these tools as a shared place for your log data, telemetry, alerts, diagnostics etc.

The Application Insights comes standard with a vast number of metrics:

Application Insights Standard Metrics

Application Insights Standard Metrics

But you can easily create any metric of your choice.

STEP ONE: CREATE A TELEMTRYCLIENT INSTANCE

First you configure a TelemetryClient instance. The InstrumentationKey is the key to your Application Insights instance:

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;

namespace MyCode
{
  public static class ApplicationInsights
  {
    public static TelemetryClient Initialize()
    {
      TelemetryConfiguration configuration = TelemetryConfiguration.Active;
      configuration.InstrumentationKey = "the-application-insights-key";
      return  new TelemetryClient(configuration);
    }
  }
}

STEP 2: LOG CUSTOM METRICS:

This is a one-line-of-code operation:

public static void TrackProcessMessageCount(TelemetryClient client, int count)
{
  client.GetMetric("Process message count").TrackValue(count);
}

The new custom metric is automatically placed in a metric namespace called “azure.applicationinsights“.

The code is used like this:

var TelemetryClient client = ApplicationInsights.TelemetryClient.Initialize();
TrackProcessMessageCount(client, 200);

You can now create a dashboard with your own custom metrics. In this example I have 3 custom metrics, and I have chosen a bar chart:

Application Insights Metrics

Application Insights Metrics

That’s all there is to it.

MORE TO READ:

Advertisements
Posted in .net, c#, Microsoft Azure | Tagged , , , , | Leave a comment

Sitecore create packages using PowerShell

The Sitecore PowerShell Extensions is a very powerful module what allows you to automate a lot of the trivial Sitecore tasks.

The Export-Package command will create a Sitecore package. This script will read a list of Sitecore item paths from a list, and add these to a package, then the package is downloaded.

The script was given to me by my colleague Adam Honoré, who should be credited.

$ItemsToBeDeployed = @(
@{ Recursive = $TRUE; Source = "master:/content/.../.../..." },
@{ Recursive = $FALSE; Source = "core:/content/.../.../..." },
...
...
);

$ErrorActionPreference = "Stop"

$Package = New-Package -Name "My Package";
$Package.Sources.Clear();
$Package.Metadata.Author = "PowerShell";
$Package.Metadata.Publisher = "Pentia";
$Package.Metadata.Version = Get-Date -Format FileDateTimeUniversal;
$Package.Metadata.Readme = 'This will install a Sitecore Package generated using PowerShell'

ForEach ($Item in $ItemsToBeDeployed)
{
  if ($Item.Recursive)
  {
    $Source = Get-Item $Item.Source | New-ItemSource -Name "N/A" -InstallMode Overwrite
    $Package.Sources.Add($Source);
  }
  else
  {
    $Source = Get-Item $Item.Source | New-ExplicitItemSource -Name "N/A" -InstallMode Overwrite
    $Package.Sources.Add($Source);
  }
}

# Save and Download Package
Export-Package -Project $package -Path "$( $package.Name ) - $( $package.Metadata.Version ).zip" -Zip
Download-File "$SitecorePackageFolder\$( $package.Name ) - $( $package.Metadata.Version ).zip"

HOW IT WORKS:

The $ItemsToBeDeployed variable contains a list of all the root items to be included in the package. Use the “Recursive” property to determine whether to include only the root item, or to include all children as well. Prefix the item path with the name of the database to get the item from.

The $Package variable is the package itself. You can set the various package properties here. The script will iterate through the $ItemsToBeDeployed variable, adding each item on the list as package sources.

Finally, the Export-Package powershell command is called to create the package, and the Download-File method is called to get the package from Sitecore.

MORE TO READ:

Posted in Sitecore 8, Sitecore 9 | Tagged , , , | Leave a comment

Improve Sitecore Experience Editor Performance by Disabling Number of Locked Items Counter

The Sitecore Experience Editor is not the fastest tool in the shed, but you can improve the performance slightly by disabling the counter on the “My items” button that shows how many items you currently have locked:

Number of locked items on button

Number of locked items on button

The setting is called WebEdit.ShowNumberOfLockedItemsOnButton and is available from Sitecore 9. You find the setting in the \App_Config\Sitecore\Experience Editor\Sitecore.ExperienceEditor.config file.

To disable the counter, simply set the value to false:

<configuration xmlns:env="http://www.sitecore.net/xmlconfig/env/" xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <settings>
      <setting name="WebEdit.ShowNumberOfLockedItemsOnButton" value="false"/>
    </settings>
  </sitecore>
</configuration>

MORE TO READ:

Posted in Sitecore 9 | Tagged , | Leave a comment

Using emojis in Sitecore

Because people younger than me stopped communicating with words and instead adopted a modern version of hieroglyphs, emojis have become a part of every modern OS and Browser, and have even been adopted by the Unicode Consortium as a standard font.

This means that you can display and select emojis from Sitecore. See the following template:

Simple Template with one emoji field

Simple Template with one emoji field

I can base an item on this template, but I have to give the item a full ASCII name, as the emoji character is an invalid character. But I can go to Emojipedia, copy the emoji from here, and use that emoji in the Display name and in the text field of my item:

Items with emojis in the display name

Items with emojis in the display name

If I make a Droplink field, Sitecore will now display the emoji. A simple trick is to use the “style” field of the Droplink field to change the font size, making the emoji a little bigger:

Using the style tag to increase the emoji size

Using the style tag to increase the emoji size

So when your user sees the emoji, it is more clear:

Dropdown with emojis

Dropdown with emojis

MORE TO READ:

 

👻
Posted in Sitecore 6, Sitecore 7, Sitecore 8, Sitecore 9 | Tagged , , | Leave a comment

SQL Cannot resolve the collation conflict between “xxx” and “xxx” in the equal to operation – Use COLLATE DATABASE_DEFAULT

When joining 2 tables from different databases, the following error might occur:

Cannot resolve the collation conflict between “SQL_Latin1_General_CP1_CI_AS” and “Danish_Norwegian_CI_AS” in the equal to operation.

This can happen when the 2 databases is created with different collations (language settings). The collation is used by the database to apply the correct sorting and comparison of fields, which is why a comparison of 2 fields with different collations cannot be executed.

If this SQL statement fails:

   select a.fieldA, b.fieldB
     from [DatabaseA].[dbo].[TableA] a
left join [DatabaseB].[dbo].[TableB] b
       on a.key = b.key

You should add COLLATE DATABASE_DEFAULT to the “on” statement.
This SQL statement will solve the collation issue:

   select a.fieldA, b.fieldB
     from [DatabaseA].[dbo].[TableA] a
left join [DatabaseB].[dbo].[TableB] b
       on a.key COLLATE DATABASE_DEFAULT = b.key COLLATE DATABASE_DEFAULT

MORE TO READ:

 

Posted in Uncategorized | Leave a comment

Sitecore Security: Roles in Roles – What it is and how it works

The Sitecore Roles-In-Roles is an extension to the basic authorization that have been around ever since Sitecore 5.

WHAT IS ROLES-IN-ROLES?

Roles-In-Roles allows you to have nested roles, so when you add a role to a user, the user is granted that role, including all the nested roles.

WHY ROLES-IN-ROLES?

The roles in Sitecore does not only grant access to content, but also to functions, such as publishing, account managing, translating etc. In an attempt to simplify the process of granting authors access to content AND functions, the idea of embedding function roles into one access role was born.
So with roles-in-roles you can create a super-role that grants access to content and functions at the same time.

WHERE DOES SITECORE STORE ROLES IN ROLES?

In the sitecore.config you will  find the rolesInRolesManager configuration setting that points to the database where the rolesinroles table is defined.

<rolesInRolesManager defaultProvider="sql" enabled="true">
  <providers>
    <clear />
    <add name="sql" type="Sitecore.Security.Accounts.SqlServerRolesInRolesProvider, Sitecore.Kernel" connectionStringName="core" rolesInRolesSupported="true" globalRolesConfigStoreName="globalRoles" raiseEvents="true" />
  </providers>
</rolesInRolesManager>

HOW DOES IT WORK?

Look at the “Developer” roles in the Roles Manager:

Roles Manager

Roles Manager

If you click the “Member Of” button you will see all the roles that is embedded into the “Developer” roles:

Roles Manager - Member Of

Roles Manager – Member Of

That means that when my user is granted the “Developer” role:

User Manager - Select Roles

User Manager – Select Roles

The user will automatically be granted the “Developer” roles, plus any embedded roles within the “Developer” role. Also, if any roles inside the “Developer” role has embedded roles, these roles are also included.

User Manager - Roles

User Manager – Roles

MORE TO READ:

Posted in Sitecore 5, Sitecore 6, Sitecore 7, Sitecore 8, Sitecore 9 | Tagged , , , , | 1 Comment

Azure Application Insights – Multiple services from same server

This trick enables you to have multiple services from the same server log to the same Application Insights instance, and at the same time distinguish between each service.

Application Insights

Application Insights Telemetry data

In the example above, I have 2 services from the same server. Each service have their own instance name. The @LTBP is a web server, and the @CloudDataloggerV1 is a windows console application.

To do this, you need to add a new TelemetryInitializer that sets the RoleInstance name.

STEP 1: CREATE NEW TELEMETRYINITIALIZER

This simple class adds the name of my service to the RoleInstance property:

internal class CloudRoleNameInitializer : ITelemetryInitializer
{
  private readonly string _roleName;

  public CloudRoleNameInitializer()
  {
    _roleName = "CloudDataLoggerV1";
  }

  public void Initialize(Microsoft.ApplicationInsights.Channel.ITelemetry telemetry)
  {
    telemetry.Context.Cloud.RoleInstance = _roleName;
  }
}

STEP 2: ADD THE TELEMETRYINITIALIZER TO THE APPLICATIONINSIGHTS INSTANCE

You can now add the CloudRoleNameInitializer to your ApplicationInsights initializing code. This example is taken from the console application’s setup code:

public static class ApplicationInsights
{
  private static TelemetryClient _telemetryClient;

  public static void Initialize()
  {
    TelemetryConfiguration configuration = TelemetryConfiguration.Active;
    configuration.InstrumentationKey = Settings.ApplicationInsights.InstrumentationKey;
    configuration.TelemetryInitializers.Add(new CloudRoleNameInitializer());
    QuickPulseTelemetryProcessor processor = null;
    configuration.TelemetryProcessorChainBuilder
      .Use((next) =>
      {
        processor = new QuickPulseTelemetryProcessor(next);
        return processor;
      })
      .Build();

    var QuickPulse = new QuickPulseTelemetryModule();
    QuickPulse.Initialize(configuration);
    QuickPulse.RegisterTelemetryProcessor(processor);

    _telemetryClient = new TelemetryClient(configuration);
    Telemetry = _telemetryClient;
  }
  public static TelemetryClient Telemetry { get; private set; }

}

MORE TO READ:

 

Posted in c#, General .NET, Microsoft Azure | Tagged , | Leave a comment

c# Async fire and forget

Often in application development you want a process to call another thread and continue the process flow, without waiting for a response from the called thread. This pattern is called the “fire and forget” pattern.

I myself are oblivious to async coding, but these methods have proven to be functioning in very large scale systems.

THE OLD WAY: USING THREADPOOL 

The System.Threading.ThreadPool method have been around since .NET 1.0. The threadpool is a pool of threads that are available for you to use. The QueueUserWorkItem puts the method into a queue and executes the method when there is an available thread.

Please note that when the async method is called, the parameter is converted into an object, and you need to cast it back to the strong type before you can work with it:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace MyNamespace
{
  public class MessageData
  {
    public string UserName { get; set; }
    public string IpAddress { get; set; }
    public string UserAgent { get; set; }
  }

  public class MyService
  {
    public static void DoWork(MessageData messageData)
    {
      ThreadPool.QueueUserWorkItem(new MyService().DoWorkAsync, messageData);
    }

    private void DoWorkAsync(object context)
    {
      try
      {
        MessageData messageData = (MessageData)context;        
        // Do stuff with the messageData object
      }
      catch (Exception ex)
      {
        // Remember that the Async code needs to handle its own
        // exceptions, as the "DoWork" method will never fail
      }
    }
  }
}

THE NEW WAY: TASK.FACTORY.STARTNEW

The Task class was introduced in .NET 4.something and is part of the new async/await keywords that makes async coding easier. The Task.Factory.StartNew() basically does the same as the TreadPool.QueueUserWorkItem but works with strong types:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace MyNamespace
{
  public class MessageData
  {
    public string UserName { get; set; }
    public string IpAddress { get; set; }
    public string UserAgent { get; set; }
  }

  public class MyService
  {
    public static void DoWork(MessageData messageData)
    {
      Task.Factory.StartNew(() => DoWorkAsync(messageData));
    }

    private void DoWorkAsync(MessageData messageData)
    {
      try
      {
        // Do stuff with the messageData object
      }
      catch (Exception ex)
      {
        // Remember that the Async code needs to handle its own
        // exceptions, as the "DoWork" method will never fail
      }
    }
  }
}

MORE TO READ:

 

Posted in .net, c#, General .NET | Tagged , , | Leave a comment

Sitecore check access and roles programatically

The Sitecore security model have changed over time, but the general API to check security access and roles have been stable for many many years.

CHECK IF USER HAS ACCESS TO AN ITEM:

To check if a user have access to a Sitecore item:

// Get Sitecore item
var item = Sitecore.Context.Database.GetItem("/sitecore/content/home/item");

// Check if the current context user 
// have read access to the item
bool canRead = item.Access.CanRead();

// Check if a named user have read access
// to an item
using (new Sitecore.Security.Accounts.UserSwitcher(@"extranet\username", true))
{
  bool canRead = item.Access.CanRead();
}

CHECK IF USER HAVE A CERTAIN ROLE:

The Sitecore User object has a Roles property, but this property does only list the immediate roles, not the roles obtained from roles-in-roles. To check for all roles, you need to use the IsInRole property:

using Sitecore.Security.Accounts;

// Get the role to check
// Remember to prefix the role name with 
// the domain name
Role role = Role.FromName(@"extranet\rolename");

// Check if user have the role
var isInRole = Sitecore.Context.User.IsInRole(role);

MORE TO READ:

Posted in .net, c#, General .NET, Sitecore 6, Sitecore 7, Sitecore 8, Sitecore 9 | Tagged , , , | 1 Comment

Sitecore 9 Caching – Sitecore.Caching.CacheManager.GetAllCaches() changed from Sitecore 8

With the increased use of dependency injection, in Sitecore, some classes do no longer return concrete classes, but interfaces instead. You therefore need to change your code, if you use the Sitecore.Caching.CacheManager. The Sitecore.Caching.Cache class is retired and have been replaced with Sitecore.Caching.ICacheInfo.

GET A LIST OF ALL CACHES:

// Get all caches, Sitecore 8
IEnumerable<Sitecore.Caching.Cache> Caches
{
  get
  {
    return CacheManager.GetAllCaches().OrderBy(c => c.Name);
  }
}


// Get all caches, Sitecore 9
IEnumerable<Sitecore.Caching.ICacheInfo> Caches
{
  get
  {
    return CacheManager.GetAllCaches().OrderBy(c => c.Name);
  }
}

CLEAR ONE CACHE ONLY:

If you wish to clear one cache only, you can no longer call Sitecore.Caching.CacheManager.FindCacheByName(cacheName), as this method is deprecated, and will result in an exception being thrown:

Unable to cast object of type ‘Sitecore.Caching.Generics.Cache`1[Sitecore.Caching.AccessResultCacheKey]’ to type ‘Sitecore.Caching.Generics.ICache`1[System.String]’.

Instead, iterate the GetAllCaches() collection and find the cache to clear:

// Calling the method from above to find a ICacheInfo object,
// then call the Clear() method
var cache = Caches.SingleOrDefault(c => c.Name == cacheName);
cache.Clear();

MORE TO READ:

Posted in Sitecore 8, Sitecore 9 | Tagged , , | 2 Comments