System.ArgumentException: Value f for keyword ALL needs to be a power of 2.

Topics: Logging Application Block, Semantic Logging Application Block
Jun 5, 2013 at 9:19 PM
When I include the keyword ALL (by un-commenting the respective line of code in the snippet below), the unit test and the application fail.
        public class Keywords
        {
            public const EventKeywords PAGE = (EventKeywords) 1;
            public const EventKeywords DATABASE = (EventKeywords) 2;
            public const EventKeywords DIAGNOSTIC = (EventKeywords) 4;
            public const EventKeywords PERF = (EventKeywords) 8;

            //public const EventKeywords ALL = PAGE | DATABASE | DIAGNOSTIC | PERF;
        }
The exception detail is:
Test Name:  ShouldValidateMainApplicationEventSourceTest
Test FullName:  SemanticLog.Tests.MainApplicationEventSourceTest.ShouldValidateMainApplicationEventSourceTest
Test Source:    SomePath\Solution\Test\SemanticLog.Tests\MainApplicationEventSourceTest.cs : line 12
Test Outcome:   Failed
Test Duration:  0:00:00.0262835

Result Message: 
Test method SemanticLog.Tests.MainApplicationEventSourceTest.ShouldValidateMainApplicationEventSourceTest threw exception: 
System.TypeInitializationException: The type initializer for 'Project7.Log.SemanticLog.MainApplicationEventSource' threw an exception. ---> System.ArgumentException: Value f for keyword ALL needs to be a power of 2.
Result StackTrace:  
at System.Diagnostics.Tracing.ManifestBuilder.AddKeyword(String name, UInt64 value)
   at System.Diagnostics.Tracing.EventSource.AddProviderEnumKind(ManifestBuilder manifest, FieldInfo staticField, String providerEnumKind)
   at System.Diagnostics.Tracing.EventSource.CreateManifestAndDescriptors(Type eventSourceType, String eventSourceDllName, EventSource source)
   at System.Diagnostics.Tracing.EventSource.InsureInitialized()
   at System.Diagnostics.Tracing.EventSource.SendCommand(EventListener listener, EventCommand command, Boolean enable, EventLevel level, EventKeywords matchAnyKeyword, IDictionary`2 commandArguments)
   at System.Diagnostics.Tracing.EventListener.EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword, IDictionary`2 arguments)
   at System.Diagnostics.Tracing.EventListener.EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword)
   at Project7.Log.SemanticLog.MainApplicationEventSource..ctor(ObservableEventListener listener) in SomePath\Solution\Logging\SemanticLog\MainApplicationEventSource.cs:line 26
   at Project7.Log.SemanticLog.MainApplicationEventSource..cctor() in SomePath\Solution\Logging\SemanticLog\MainApplicationEventSource.cs:line 20
 --- End of inner exception stack trace ---
    at SemanticLog.Tests.MainApplicationEventSourceTest.ShouldValidateMainApplicationEventSourceTest() in SomePath\Solution\Test\SemanticLog.Tests\MainApplicationEventSourceTest.cs:line 13
The developer guide says:
If you want to activate events in all groups, you must use the Keywords.All parameter value. If you
do not supply a value for this optional parameter, only events with no keywords are active.
And give the sample code:
class Program
{
static void Main(string[] args)
{
// Create the event listener
ObservableEventListener listener = new ObservableEventListener();
listener.EnableEvents(MyCompanyEventSource.Log, EventLevel.LogAlways,
Keywords.All);
listener.LogToConsole();
MyCompanyEventSource.Log.StartUp();
...
listener.DisableEvents(MyCompanyEventSource.Log);
listener.Dispose();
}
}
and
public class Keywords
{
public const EventKeywords Page = (EventKeywords)1;
public const EventKeywords DataBase = (EventKeywords)2;
public const EventKeywords Diagnostic = (EventKeywords)4;
public const EventKeywords Perf = (EventKeywords)8;
}
I know that every flag has to be set to the power of 2, but I don't know what's wrong with my "ALL" value.

What could be wrong?
Jun 5, 2013 at 9:59 PM
If you want to enable all keywords use the built-in constant: Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Keywords.All which is defined as -1.

Your value of All (PAGE | DATABASE | DIAGNOSTIC | PERF) is not a multiple of 2 so it causes the manifest builder to throw.

If you wanted to define other combination of Keyword constants it would have to be outside of the Keywords class. However, most of the time it's probably fine to just specify inline when configuring logging:
// Create the event listener
// alternate value outside of Keywords nested class: 
//EventKeyWords MostlyAll = MyCompanyEventSource.Keywords.Page | MyCompanyEventSource.Keywords.DataBase |
//                          MyCompanyEventSource.Keywords.Perf;     
ObservableEventListener listener = new ObservableEventListener();
listener.EnableEvents(MyCompanyEventSource.Log, EventLevel.LogAlways,
MyCompanyEventSource.Keywords.Page | MyCompanyEventSource.Keywords.DataBase | MyCompanyEventSource.Keywords.Diagnostic | MyCompanyEventSource.Keywords.Perf);
listener.LogToConsole();
~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Jun 5, 2013 at 10:06 PM
Thanks for the reply. I already tried using Enable function the way you described but I am wondering where the guide came from about that Keywords.All? randylevy <[email removed]> wrote: From: randylevy If you want to enable all keywords use the built-in
constant: Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Keywords.All which is defined as -1. Your value of All (PAGE | DATABASE | DIAGNOSTIC | PERF) is not a multiple of 2 so it causes the manifest builder to throw. If you wanted to define other combination
of Keyword constants it would have to be outside of the Keywords class. However, most of the time it's probably fine to just specify inline when configuring logging: // Create the event listener // alternate value outside of Keywords nested class: //EventKeyWords
MostlyAll = MyCompanyEventSource.Keywords.Page | MyCompanyEventSource.Keywords.DataBase | // MyCompanyEventSource.Keywords.Perf; ObservableEventListener listener = new ObservableEventListener(); listener.EnableEvents(MyCompanyEventSource.Log, EventLevel.LogAlways,
MyCompanyEventSource.Keywords.Page | MyCompanyEventSource.Keywords.DataBase | MyCompanyEventSource.Keywords.Diagnostic | MyCompanyEventSource.Keywords.Perf); listener.LogToConsole(); ~~ Randy Levy [email removed]<mailto:[email removed]> Enterprise Library
support engineer Support How-to<entlib.codeplex.com/wikipage?title=Support%20How-to> Read the full discussion online<http://entlib.codeplex.com/discussions/446129#post1053293>. To add a post to this discussion, reply to this email ([email removed]<mailto:[email
removed]?subject=[entlib:446129]>) To start a new discussion for this project, email [email removed]<mailto:[email removed]> You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe<http://entlib.codeplex.com/discussions/446129/unsubscribe/>
on CodePlex.com. Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com