-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'GitHub/shuriken/feature/v1.1' into GitHub/shuriken/master
- Loading branch information
Showing
87 changed files
with
4,783 additions
and
1,187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Logging and Performance Monitoring | ||
|
||
The [Shuriken](../README.md) library makes extensive use of the Event Tracing for Windows (ETW) for logging as well as for reporting performance. | ||
|
||
## Logging | ||
|
||
The following table contains the explosed events: | ||
|
||
|Event Name|Event ID|Event Level|Opcode|Payload|Message| | ||
---|---:|---|---|---|--- | ||
|`MonitorStart`|1|Informational|Start||Monitor has been started.| | ||
|`MonitorStop`|2|Informational|Stop||Monitor has been stopped.| | ||
|`MonitorSuspend`|3|Informational|Suspend||Monitor has been suspended.| | ||
|`MonitorResume`|4|Informational|Resume||Monitor has been resumed.| | ||
|`StoppingDueToFailedUpdate`|5|Error|Info|`exception`|Stopping the monitoring because of an exception while updating the values: {0}| | ||
|`StoppingDueToFailedChangeNotifications`|6|Error|Info|`exception`|Stopping the monitoring because of an exception while sending the change notifications: {0}| | ||
|`FailedAttachingSystemEvent`|7|Warning|Info|`systemEvent`, `exception`|Failed attaching the system event '{0}': {1}| | ||
|`MissingMonitoringScope`|8|Warning|Info|`eventName`, `scope`|The {0} event handler is assigned, but the {1} is not available.| | ||
|`UnableInitiallyToReadProperty`|9|Warning|Info|`type`, `property`, `exception`|Cannot initially get the value of the '{1}' property of the '{0}' object: {2}| | ||
|`UnableSubsequentlyToReadProperty`|10|Warning|Info|`type`, `property`, `exception`|Cannot get the value of the '{1}' property of the '{0}' object: {2}| | ||
|`UnableInitiallyToInvokeCommandMethod`|11|Warning|Info|`type`, `property`, `method`, `exception`|Cannot initially invoke the '{2}' method of the '{1}' property of the '{0}' object: {3}| | ||
|`UnableSubsequentlyToInvokeCommandMethod`|12|Warning|Info|`type`, `property`, `method`, `exception`|Cannot invoke the '{2}' method of the '{1}' property of the '{0}' object: {3}| | ||
|`UnableToAnalyzeProperty`|13|Warning|Info|`type`, `property`, `exception`|Cannot analyze the value of the '{1}' property of the '{0}' object: {2}| | ||
|`UnableToRaisePropertyChangeNotification`|14|Warning|Info|`type`, `property`, `exception`|Cannot raise the change notification for the '{1}' property of the '{0}' object: {2}| | ||
|`UnableToRaiseCommandPropertyChangeNotification`|15|Warning|Info|`type`, `property`, `exception`|Cannot raise the change notification for the '{1}' command property of the '{0}' object: {2}| | ||
|`CommandFailed`|16|Warning|Info|`exception`|Command execution failed: {0}| | ||
|
||
All logging events are traced to the *Operational* channel. | ||
|
||
## Measuring Performance | ||
|
||
The following table contains the explosed events: | ||
|
||
|Event Name|Event ID|Payload|Remarks| | ||
---|---:|---|--- | ||
|`PerformanceMonitoredProperties`|19|`count`|Number of monitored properties. Lower value is better. A high value can indicate an unnecessary observation or memory leaks (e.g. due to missing UI virtualization).| | ||
|`PerformanceCycleTime`|20|`elapsedMilliseconds`|Complete cycle time [ms]. Lower value is better. For smooth performance it should not exceed 15ms.| | ||
|`PerformanceLists`|21|`capacityThreadAffine`, `countThreadAffine`, `capacityThreadSafe`, `countThreadSafe`|Total number and number of used slots.| | ||
|`PerformanceListsWithChangedProperties`|22|`capacityThreadAffine`, `countThreadAffine`, `capacityThreadSafe`, `countThreadSafe`|Total number and number of used slots with changed properties.| | ||
|`PerformanceListsWithItemsToBeRemoved`|23|`capacityThreadAffine`, `countThreadAffine`, `capacityThreadSafe`, `countThreadSafe`|Total number and number of used slots with items to be removed.| | ||
|
||
All performance-related events are traced to the *Analytic* channel. | ||
|
||
## Capturing Events from the Application | ||
|
||
Use the static events of the `Shuriken.Diagnostics.EventListener` class to receive notifications when events are traced. | ||
|
||
### Using the Output Window in Visual Studio | ||
|
||
Capture events from the *Operational* channel and create debug message using the `ToDebugMessage` extension method (also defined in the `Shuriken.Diagnostics.EventListener` class). Consider surrounding the tracing with the `#if DEBUG` directive when the event handler only invokes the `Debug.WriteLine` method: | ||
|
||
```csharp | ||
[STAThread] | ||
static void Main() | ||
{ | ||
#if DEBUG | ||
Shuriken.Diagnostics.EventListener.OperationalEvent += (_, e) => Debug.WriteLine(e.ToDebugMessage()); | ||
#endif | ||
|
||
var app = new App(); | ||
app.InitializeComponent(); | ||
|
||
var applicationMonitorScope = new ApplicationMonitorScope(new WpfNotificationContext(app.Dispatcher)); | ||
try | ||
{ | ||
app.Run(); | ||
} | ||
finally | ||
{ | ||
applicationMonitorScope.Dispose().GetAwaiter().GetResult(); | ||
} | ||
} | ||
``` | ||
|
||
*Note:* use this approach to be notified when observed properties, commands' `CanExecute` and `Execute` methods throw exceptions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Guidelines | ||
|
||
The [Shuriken](../README.md) library provides the base class `ObservableObject` (which implements the `INotifyPropertyChanged` interface). | ||
|
||
In order to provide public observable properties (e.g. for binding) use the following guidelines to define properties: | ||
|
||
|Case|Guideline|Behavior when annotated with the `[Observable]` attribute| | ||
---|---|--- | ||
|Regular properties|**Always** annotate the property with the `[Observable]` attribute.|The property values are tracked automatically.| | ||
|Immutable properties|**Never** annotate the property with the `[Observable]` attribute. It's not needed to track the property values as they never change.|The property values are tracked, however, as property values never change it just consumes valuable resources.| | ||
|Indexer|**Never** annotate the property with the `[Observable]` attribute. An indexer cannot be tracked automatically. Use the `NotifyIndexerChange` method to send notifications.|The indexer values are *not* tracked.| | ||
|`Command` properties\*|**Consider** annotating the property with the `[Observable]` attribute. Even if the property is immutable (never changes) the `CanExecute` can change. However, if the `CanExecute` never changes the property should not be annotated with the `[Observable]` attribute.|The property values (the `Command` objects) as well as the `CanExecute` are tracked automatically.<br>*Note:* the `CanExecute` always returns `false` while the command is being executed.| | ||
|`AsyncCommand` properties\*|**Always** annotate the property with the `[Observable]` attribute. Even if the property is immutable (never changes) the `CanExecute` can change.|The property values (the `AsyncCommand` objects) as well as the `CanExecute` are tracked automatically.<br>*Note:* the `CanExecute` always returns `false` while the command is being executed.| | ||
|`Command<T>` properties\*|**Consider not** annotating the property with the `[Observable]` attribute. Changes of `CanExecute(T)` cannot be tracked automatically. Use the `NotifyCanExecuteChanged` method to send notifications. Only if the property is not immutable it should be annotated with the `[Observable]` attribute.|The property values (the `Command<T>` objects) are tracked, but the `CanExecute(T)` are not tracked.<br>*Note:* the `CanExecute(T)` always returns `false` while the command is being executed.| | ||
|`AsyncCommand<T>` properties\*|**Always** annotate the property with the `[Observable]` attribute. Even if the property is immutable (never changes) and the `CanExecute(T)` cannot be tracked automatically the method will always return `false` while the command is being executed.|The property values (the `AsyncCommand<T>` objects) are tracked, but the `CanExecute(T)` are not tracked.<br>*Note:* the `CanExecute(T)` always returns `false` while the command is being executed.| | ||
|`ICommand` properties\*|**Consider not** annotating the property with the `[Observable]` attribute. Changes of `CanExecute(object)` cannot be tracked automatically. Only if the property is not immutable it should be annotated with the `[Observable]` attribute.|The property values (the `ICommand` objects) are tracked, but the `CanExecute(object)` are not tracked.| | ||
|
||
\* declared property types | ||
|
||
*Note:* the `[Observable]` annotation does nothing if the class doesn't derive from the `ObservableObject` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.