-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
bnbdr
committed
Jan 17, 2020
1 parent
1e75b24
commit a4e48df
Showing
14 changed files
with
1,671 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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,93 @@ | ||
# TraceLogging for Python | ||
This small package implements a `TraceLoggingProvider` for publishing ETW events in **Windows**. | ||
|
||
|
||
**Use at your own risk.** | ||
|
||
# Requirements | ||
- python 3.8.x | ||
|
||
# Installation | ||
```bash | ||
pip install tracelogging | ||
``` | ||
|
||
# Usage | ||
All usage examples are assuming an enabled EventTrace session for the provider(you can use [EtwConsumer](./SampleEtwConsumer/))). | ||
|
||
TheFollowing examples are taken from [here](./examples/) | ||
|
||
## Basic logging for the extremely lazy | ||
Similar usage to python's own logging. No handlers, no formatters, no `exception` method, no format or additional arguments supported. | ||
|
||
|
||
The name given to a provider will be used to generate the appropriate GUID the same way `TraceEvent` does. | ||
```py | ||
import tracelogging | ||
log = tracelogging.getLogger('MyLoggerName') | ||
|
||
log.debug('ging') | ||
log.info('rmation') | ||
log.warning('be careful') | ||
log.error('err') | ||
log.critical('oh no!') | ||
``` | ||
|
||
|
||
## Defining your very own provider | ||
Defines a provider named `PythonProvider` that can publish an event named `BasicEvent` without any additional data | ||
```py | ||
from tracelogging import Provider, event | ||
|
||
class PythonProvider(Provider): | ||
@event() # mind the parentheses | ||
def BasicEvent(self): | ||
pass | ||
|
||
log = PythonProvider() | ||
log.BasicEvent() | ||
``` | ||
|
||
## Advanced usage | ||
You can override the provider's `Name` directly by setting the `Name` class member to whatever you wish. | ||
Same can be done with the `Guid` member, by setting it to an instance of `UUID` with the desired value. | ||
|
||
|
||
You can set values for the event's descriptor using the `event` decoraotr, just like you would with `TraceEvent` ([or EVENT_DESCRIPTOR struct](https://docs.microsoft.com/en-us/windows/win32/api/evntprov/ns-evntprov-event_descriptor)). You may also specify an override to the event name. | ||
|
||
In order to add data to the event, you must use python's type-hinting with the supported types(see Types) | ||
```py | ||
from tracelogging import Provider, event, Types, TraceLevel | ||
|
||
class PythonProvider(Provider): | ||
Name = 'Company-Product-Component' | ||
|
||
@event(Name='FileSize', Id=1, Level=TraceLevel.Warning, Keyword=0x01) | ||
def not_a_nice_event_name(self, file_path:Types.UnicodeString, file_size:Types.UInt32): | ||
print('this will be called after the event is written, if you wish to implement anything here') | ||
|
||
log = PythonProvider() | ||
log.not_a_nice_event_name('C:\\windows\\system32\\calc.exe', 0x1000) # will send event named 'FileSize' | ||
``` | ||
|
||
## Current supported types | ||
Type | Python | Description | ||
--|--|-- | ||
`UnicodeString` | `str` | null terminated UTF-16 string | ||
`CountedUnicodeString` | `str` | size prefix (WORD) followed by UTF-16 string (not terminated) | ||
`UInt32` | `int` | unsigned DWORD | ||
`Int32` | `int` | signed DWORD | ||
`UInt64` | `int` | unsigned QWORD | ||
`Int64` | `int` | signed QWORD | ||
|
||
# Notes | ||
- Read contents of `TraceLoggingProvider.h` header for more info | ||
- Most logic is performed during provider class definition. Instantiation only registers and 'sets' the provider as one capable of sending self-described events | ||
- Providers can inherit events from base classes, though doing so is discouraged. | ||
- Internal code uses a sort of singleton to prevent multiple instances of the same provider | ||
|
||
# License | ||
MIT | ||
|
||
# Troubleshooting | ||
set environment variable `TLG_LOG` to the desired log level (1 for high verbosity, 0 to turn off) |
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,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 15 | ||
VisualStudioVersion = 15.0.27703.2000 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EtwConsumer", "EtwConsumer\EtwConsumer.csproj", "{EE0AB704-AFE5-40DB-9F65-2C25BBADF24A}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{EE0AB704-AFE5-40DB-9F65-2C25BBADF24A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{EE0AB704-AFE5-40DB-9F65-2C25BBADF24A}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{EE0AB704-AFE5-40DB-9F65-2C25BBADF24A}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{EE0AB704-AFE5-40DB-9F65-2C25BBADF24A}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {C38F90C1-423F-4591-B00B-6E367EC9BAD9} | ||
EndGlobalSection | ||
EndGlobal |
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,6 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<configuration> | ||
<startup> | ||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> | ||
</startup> | ||
</configuration> |
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,79 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\build\Microsoft.Diagnostics.Tracing.TraceEvent.props" Condition="Exists('..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\build\Microsoft.Diagnostics.Tracing.TraceEvent.props')" /> | ||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<ProjectGuid>{EE0AB704-AFE5-40DB-9F65-2C25BBADF24A}</ProjectGuid> | ||
<OutputType>Exe</OutputType> | ||
<RootNamespace>EtwConsumer</RootNamespace> | ||
<AssemblyName>EtwConsumer</AssemblyName> | ||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> | ||
<FileAlignment>512</FileAlignment> | ||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | ||
<NuGetPackageImportStamp> | ||
</NuGetPackageImportStamp> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||
<PlatformTarget>AnyCPU</PlatformTarget> | ||
<DebugSymbols>true</DebugSymbols> | ||
<DebugType>full</DebugType> | ||
<Optimize>false</Optimize> | ||
<OutputPath>bin\Debug\</OutputPath> | ||
<DefineConstants>DEBUG;TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||
<PlatformTarget>AnyCPU</PlatformTarget> | ||
<DebugType>pdbonly</DebugType> | ||
<Optimize>true</Optimize> | ||
<OutputPath>bin\Release\</OutputPath> | ||
<DefineConstants>TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Reference Include="Dia2Lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | ||
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\lib\net45\Dia2Lib.dll</HintPath> | ||
<EmbedInteropTypes>True</EmbedInteropTypes> | ||
</Reference> | ||
<Reference Include="Microsoft.Diagnostics.FastSerialization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | ||
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\lib\net45\Microsoft.Diagnostics.FastSerialization.dll</HintPath> | ||
</Reference> | ||
<Reference Include="Microsoft.Diagnostics.Tracing.TraceEvent, Version=2.0.49.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | ||
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\lib\net45\Microsoft.Diagnostics.Tracing.TraceEvent.dll</HintPath> | ||
</Reference> | ||
<Reference Include="OSExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | ||
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\lib\net45\OSExtensions.dll</HintPath> | ||
</Reference> | ||
<Reference Include="System" /> | ||
<Reference Include="System.Core" /> | ||
<Reference Include="System.Xml.Linq" /> | ||
<Reference Include="System.Data.DataSetExtensions" /> | ||
<Reference Include="Microsoft.CSharp" /> | ||
<Reference Include="System.Data" /> | ||
<Reference Include="System.Net.Http" /> | ||
<Reference Include="System.Xml" /> | ||
<Reference Include="TraceReloggerLib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | ||
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\lib\net45\TraceReloggerLib.dll</HintPath> | ||
<EmbedInteropTypes>True</EmbedInteropTypes> | ||
</Reference> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="Program.cs" /> | ||
<Compile Include="Properties\AssemblyInfo.cs" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Include="App.config" /> | ||
<None Include="packages.config" /> | ||
</ItemGroup> | ||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | ||
<PropertyGroup> | ||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | ||
</PropertyGroup> | ||
<Error Condition="!Exists('..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\build\Microsoft.Diagnostics.Tracing.TraceEvent.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.2.0.49\build\Microsoft.Diagnostics.Tracing.TraceEvent.props'))" /> | ||
</Target> | ||
</Project> |
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,51 @@ | ||
using Microsoft.Diagnostics.Tracing; | ||
using Microsoft.Diagnostics.Tracing.Session; | ||
using System; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace EtwConsumer | ||
{ | ||
class Program | ||
{ | ||
static void Main(string[] providerNames) | ||
{ | ||
var sessionName = "SampleEtwConsumerSession"; | ||
|
||
Console.WriteLine($"Creating session: '{sessionName}'"); | ||
using (var session = new TraceEventSession(sessionName)) | ||
{ | ||
Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e) | ||
{ | ||
Console.WriteLine("stopping"); | ||
session.Dispose(); | ||
}; | ||
|
||
session.Source.Dynamic.AddCallbackForProviderEvents((providerName, eventName) => | ||
{ | ||
return EventFilterResponse.AcceptEvent; | ||
}, eventData => | ||
{ | ||
Console.WriteLine(eventData.ToString()); | ||
}); | ||
|
||
foreach (var name in providerNames) | ||
{ | ||
if (name.StartsWith("{") && name.EndsWith("}")) | ||
{ | ||
var guid = new Guid(name); | ||
session.EnableProvider(guid, TraceEventLevel.Verbose); | ||
Console.WriteLine($"enabled {guid}"); | ||
} | ||
else | ||
{ | ||
session.EnableProvider(name, TraceEventLevel.Verbose); | ||
Console.WriteLine($"enabled {name}"); | ||
} | ||
} | ||
|
||
session.Source.Process(); | ||
} | ||
} | ||
} | ||
} |
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,36 @@ | ||
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("EtwConsumer")] | ||
[assembly: AssemblyDescription("")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("")] | ||
[assembly: AssemblyProduct("EtwConsumer")] | ||
[assembly: AssemblyCopyright("Copyright © 2020")] | ||
[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("ee0ab704-afe5-40db-9f65-2c25bbadf24a")] | ||
|
||
// 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")] |
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,4 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<packages> | ||
<package id="Microsoft.Diagnostics.Tracing.TraceEvent" version="2.0.49" targetFramework="net461" /> | ||
</packages> |
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,10 @@ | ||
import tracelogging | ||
|
||
log = tracelogging.getLogger('MyLoggerName') | ||
|
||
# run: EtwConsumer.exe MyLoggerName | ||
log.debug('ging') | ||
log.info('rmation') | ||
log.warning('be careful') | ||
log.error('err') | ||
log.critical('oh no!') |
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,11 @@ | ||
from tracelogging import Provider, event | ||
|
||
class PythonProvider(Provider): | ||
@event() # mind the parentheses | ||
def BasicEvent(self): | ||
pass | ||
|
||
log = PythonProvider() | ||
|
||
# run: EtwConsumer.exe PythonProvider | ||
log.BasicEvent() |
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,12 @@ | ||
from tracelogging import Provider, event, Types, TraceLevel | ||
|
||
class PythonProvider(Provider): | ||
Name = 'Company-Product-Component' | ||
|
||
@event(Name='FileSize', Id=1, Level=TraceLevel.Warning, Keyword=0x01) | ||
def not_a_nice_event_name(self, file_path:Types.UnicodeString, file_size:Types.UInt32): | ||
print('this will be called after the event is written, if you wish to implement anything here') | ||
|
||
# run: EtwConsumer.exe Company-Product-Component | ||
log = PythonProvider() | ||
log.not_a_nice_event_name('C:\\windows\\system32\\calc.exe', 0x1000) # will send event named 'FileSize' |
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,24 @@ | ||
from setuptools import setup | ||
import tracelogging | ||
|
||
|
||
author = 'bnbdr' | ||
setup( | ||
name='tracelogging', | ||
version='.'.join(map(str, tracelogging.version)), | ||
author=author, | ||
author_email='bad.32@outlook.com', | ||
url='https://github.com/{}/tracelogging'.format(author), | ||
description="python tracelogging for windows", | ||
long_description=tracelogging.__doc__, | ||
long_description_content_type="text/markdown", | ||
license='MIT', | ||
keywords='windows tracelogging python etw trace', | ||
py_modules=['tracelogging'], | ||
classifiers=[ | ||
"Intended Audience :: Developers", | ||
"Programming Language :: Python :: 3", | ||
"License :: OSI Approved :: MIT License", | ||
"Operating System :: Microsoft :: Windows", | ||
], | ||
) |
Oops, something went wrong.