Share via


Managing Custom Areas and Categories

The latest release of the SharePoint Logger allows you to create custom diagnostic areas and categories for your SharePoint applications. This enables system administrators to apply event throttling rules to your applications in the same way that they configure logging and reporting from the SharePoint application itself.

The SharePoint Logger includes a class named DiagnosticsAreaCollection that is responsible for loading and saving your diagnostic areas and categories. The DiagnosticsAreaCollection class extends a generic collection of DiagnosticsArea objects that represent your custom areas. Each DiagnosticsArea object contains a DiagnosticsCategoryCollection object. This consists of a collection of DiagnosticsCategory objects that represent the custom categories within each area. The following illustration shows this relationship.

Diagnostic areas and categories

Ff798462.126b8377-4e67-4df2-9550-6982ded9bdc6(en-us,PandP.10).png

Typically, you should use a feature receiver class to configure your custom areas and categories when you install your application. Because your solution may contain several features that use the areas and categories you define, a recommended practice is to define your areas and categories within a farm-scoped feature in your solution. This ensures that your areas and categories are available when the solution is deployed, and will remain available until the solution is retracted. If you add any new areas, you will also need to create corresponding event sources on each Web front-end (WFE) server in your farm, because event sources are specific to individual computers. For more information about this scenario, see Using Feature Receivers to Configure Diagnostic Areas and Categories.

Note

Although you can add your own custom categories to the built-in diagnostic areas in SharePoint 2010, this is considered bad practice. Instead, you should create your own custom areas and categories for your SharePoint applications.

Adding Custom Areas and Categories

Whenever you work with custom areas and categories, your first task will always be to construct an object of type DiagnosticsAreaCollection. The DiagnosticsAreaCollection class provides two constructors:

  • A default constructor. This creates an empty collection.
  • A constructor that takes an argument of type IConfigManager. This creates a collection and populates it with the custom diagnostic areas and categories that have already been configured in the current server farm.

The IConfigManager interface is provided by the The Application Setting Manager component. The SharePoint Logger uses the Configuration Manager to persist and retrieve custom areas and categories. Because of this, if you plan to persist additions, updates or deletions to the areas or categories, or if you want to retrieve the areas and categories that are already configured, you must include an IConfigManager argument when you instantiate a DiagnosticsAreaCollection object.

The default constructor is useful if you want to build a collection of areas and categories before you persist them to the SharePoint environment. For example, you might use a property to build your collection using the default DiagnosticsAreaCollection constructor.

public class ConfigureLogging
{
    DiagnosticsAreaCollection _myAreas = null;
    DiagnosticsAreaCollection MyAreas
    {
        get
        {
            if (_myAreas == null)
            {
                _myAreas = new DiagnosticsAreaCollection();
                DiagnosticsArea newArea = new DiagnosticsArea("HelpDesk");
                newArea.DiagnosticsCategories.Add(new DiagnosticsCategory(
                    "Execution", EventSeverity.Warning, TraceSeverity.Medium));
                newArea.DiagnosticsCategories.Add(new DiagnosticsCategory(
                    "Data", EventSeverity.Error, TraceSeverity.Medium));
                DiagnosticsArea newArea1 = new DiagnosticsArea("CRM");
                newArea1.DiagnosticsCategories.Add(new DiagnosticsCategory(
                    "LostSale", EventSeverity.Warning, TraceSeverity.Medium));
                newArea1.DiagnosticsCategories.Add(new DiagnosticsCategory(
                  "TransactionError", EventSeverity.Error, TraceSeverity.Medium));
                _myAreas.Add(newArea);
                _myAreas.Add(newArea1);
            }
            return _myAreas;
        }
    }

When you want to persist your collection of areas and categories to the SharePoint environment, you use the constructor that takes an argument of type IConfigManager. This creates a definitive collection that contains all the custom areas and categories that have already been configured.

    public void AddAreasToConfiguration()
    {
        IConfigManager configMgr =
            SharePointServiceLocator.GetCurrent().GetInstance<IConfigManager>();

         DiagnosticsAreaCollection configuredAreas = new
            DiagnosticsAreaCollection(configMgr);

After you create the pre-populated DiagnosticsAreaCollection object, you can add your new areas and categories to the collection. After you finish adding your areas, call the SaveConfiguration method to persist your areas (and any categories that you created within your areas) to the SharePoint environment.

    foreach (DiagnosticsArea newArea in MyAreas)
   {
        configuredAreas.Add(newArea);
    }

    configuredAreas.SaveConfiguration();
   }

Note

If you used the default constructor to create your DiagnosticsAreaCollection object, an InvalidOperationException will be thrown if you call the SaveConfiguration method. This is because the DiagnosticsAreaCollection needs a reference to the Configuration Manager in order to persist areas and categories as configuration data.

If you attempt to add an area that already exists, an InvalidOperationException will be thrown. A safer approach is to check that areas or categories do not already exist before you add them.

    foreach (DiagnosticsArea newArea in MyAreas)
    {
        var existingArea = configuredAreas[newArea.Name];

        if (existingArea == null)
        {
            configuredAreas.Add(newArea);
        }
        else
        {
            foreach (DiagnosticsCategory c in newArea.DiagnosticsCategories)
            {
                var existingCategory = existingArea.DiagnosticsCategories[c.Name];
                if (existingCategory == null)
                {
                    existingArea.DiagnosticsCategories.Add(c);
                }
            }
        }
    }

When you create a new diagnostic category, you can specify default throttling values for event severity and trace severity in addition to a category name. For example, if you set the event severity value to Information, any events in this category will only be reported to the event log if they have a severity value equal to or higher than Information. The system administrator can change these throttling settings at any time through the Central Administration Web site.

DiagnosticsCategory newCategory = new DiagnosticsCategory("Projects",  
 EventSeverity.Information, TraceSeverity.Medium);

If you do not specify an event severity or a trace severity, by default, the category uses an event severity of Warning and a trace severity of Medium.

Removing Custom Areas and Categories

The process for removing areas and categories is similar to the process for adding areas and categories. First, you must construct the DiagnosticsAreaCollection object by using the constructor that takes an argument of type IConfigManager. Next, use the Remove method to remove individual areas. Finally, call the SaveConfiguration method to persist your changes.

IConfigManager configMgr =
    SharePointServiceLocator.GetCurrent().GetInstance<IConfigManager>();
DiagnosticsAreaCollection configuredAreas = new
    DiagnosticsAreaCollection(configMgr);

foreach (DiagnosticsArea area in MyAreas)
{
  DiagnosticsArea areaToRemove = configuredAreas[area.Name];

  if (areaToRemove != null)
  {  
    configuredAreas.Remove(areaToRemove);
  }
}
configuredAreas.SaveConfiguration();

Take care when removing areas, because other users may have added categories for applications that are still deployed. The safest way to remove your logging configuration is to remove all your own categories, and then if no categories remain, remove the area.

foreach (DiagnosticsArea area in MyAreas)
{
  DiagnosticsArea areaToRemove = configuredAreas[area.Name];

  if (areaToRemove != null)
  {
    foreach (DiagnosticsCategory c in area.DiagnosticsCategories)
    {
      var existingCat = areaToRemove.DiagnosticsCategories[c.Name];
      if (existingCat != null)
        {
          areaToRemove.DiagnosticsCategories.Remove(existingCat);
        }
      }
      if (areaToRemove.DiagnosticsCategories.Count == 0)
      {
        configuredAreas.Remove(areaToRemove);
      }
    }
  }
}