-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Redirect ETW logging to Syslog on Linux #5144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
479559d
ebfbdcf
536eb44
36c25c8
4e23d84
e8f138e
aff9e61
b529cba
ffb7a88
31f20e4
3db6101
1dfb014
731c5e1
c8372e8
9e4465a
c875f8d
99cf86d
89782f3
e20ca59
e7901fe
4e04118
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
| using System.Threading; | ||
|
|
||
| using System.Management.Automation; | ||
| using System.Management.Automation.Internal; | ||
| using Microsoft.Win32; | ||
|
|
||
| using Newtonsoft.Json; | ||
|
|
@@ -101,6 +102,51 @@ internal enum PropertyScope | |
| internal abstract string GetDefaultSourcePath(); | ||
| internal abstract void SetDefaultSourcePath(string defaultPath); | ||
|
|
||
| #if UNIX | ||
| /// <summary> | ||
| /// Gets the application identity (name) to use for writing to syslog. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// The string identity to use for writing to syslog. | ||
| /// <para> | ||
| /// The default value is 'powershell' | ||
|
||
| /// </para> | ||
| /// </returns> | ||
| internal abstract string GetSysLogIdentity(); | ||
|
|
||
| /// <summary> | ||
| /// Gets the log level filter. | ||
| /// </summary> | ||
| /// <returns>One of the PSLevel values indicating the level to log. | ||
| /// <para> | ||
| /// The default value is PSLevel.Informational | ||
|
||
| /// </para> | ||
| /// </returns> | ||
| internal abstract PSLevel GetLogLevel(); | ||
|
|
||
| /// <summary> | ||
| /// Gets the bitmask of the PSChannel values to log. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// A bitmask of PSChannel.Operational and/or PSChannel.Analytic | ||
|
||
| /// <para> | ||
| /// The default value is PSChannel.Operational | ||
|
||
| /// </para> | ||
| /// </returns> | ||
| internal abstract PSChannel GetLogChannels(); | ||
|
|
||
| /// <summary> | ||
| /// Gets the bitmask of keywords to log. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// A bitmask of PSKeyword values. | ||
| /// <para> | ||
| /// The default value is all keywords other than UseAlwaysAnalytic | ||
|
||
| /// </para> | ||
| /// </returns> | ||
| internal abstract PSKeyword GetLogKeywords(); | ||
|
|
||
| #endif // UNIX | ||
| #endregion // Interface Methods | ||
| } | ||
|
|
||
|
|
@@ -310,6 +356,155 @@ internal override void SetDefaultSourcePath(string defaultPath) | |
| WriteValueToFile<string>(fileName, "DefaultSourcePath", defaultPath); | ||
| } | ||
|
|
||
| #if UNIX | ||
| /// <summary> | ||
| /// Gets the identity name to use for writing to syslog. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// The string identity to use for writing to syslog. | ||
| /// <para> | ||
| /// The default value is 'powershell'. | ||
| /// </para> | ||
| /// </returns> | ||
| internal override string GetSysLogIdentity() | ||
| { | ||
| string fileName = Path.Combine(psHomeConfigDirectory, configFileName); | ||
| string identity = ReadValueFromFile<string>(fileName, "LogIdentity"); | ||
|
||
|
|
||
| if (string.IsNullOrEmpty(identity) || | ||
| identity.Equals(LogDefaultValue, StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| identity = "powershell"; | ||
| } | ||
| return identity; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the log level filter. | ||
| /// </summary> | ||
| /// <returns>One of the PSLevel values indicating the level to log. | ||
| /// <para> | ||
| /// The default value is PSLevel.Informational. | ||
| /// </para> | ||
| /// </returns> | ||
| internal override PSLevel GetLogLevel() | ||
| { | ||
| string fileName = Path.Combine(psHomeConfigDirectory, configFileName); | ||
| string levelName = ReadValueFromFile<string>(fileName, "LogLevel"); | ||
| PSLevel level; | ||
|
|
||
| if (string.IsNullOrEmpty(levelName) || | ||
| levelName.Equals(LogDefaultValue, StringComparison.OrdinalIgnoreCase) || | ||
| !Enum.TryParse<PSLevel>(levelName, true, out level)) | ||
| { | ||
| level = PSLevel.Informational; | ||
| } | ||
| return level; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The supported separator characters for listing channels and keywords in configuration. | ||
| /// </summary> | ||
| static readonly char[] s_valueSeparators = new char[] {' ', ',', '|'}; | ||
|
||
|
|
||
| /// <summary> | ||
| /// Provides a string name to indicate the default for a configuration setting. | ||
| /// </summary> | ||
| const string LogDefaultValue = "default"; | ||
|
|
||
| const PSChannel DefaultChannels = PSChannel.Operational; | ||
|
|
||
| /// <summary> | ||
| /// Gets the bitmask of the PSChannel values to log. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// A bitmask of PSChannel.Operational and/or PSChannel.Analytic. | ||
| /// <para> | ||
| /// The default value is PSChannel.Operational. | ||
| /// </para> | ||
| /// </returns> | ||
| internal override PSChannel GetLogChannels() | ||
| { | ||
| string fileName = Path.Combine(psHomeConfigDirectory, configFileName); | ||
| string values = ReadValueFromFile<string>(fileName, "LogChannels"); | ||
|
|
||
| PSChannel result = 0; | ||
| if (!string.IsNullOrEmpty(values)) | ||
| { | ||
| string[] names = values.Split(s_valueSeparators, StringSplitOptions.RemoveEmptyEntries); | ||
|
|
||
| foreach (string name in names) | ||
| { | ||
| if (name.Equals(LogDefaultValue, StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| result = 0; | ||
| break; | ||
| } | ||
|
|
||
| PSChannel value; | ||
| if (Enum.TryParse<PSChannel>(name, true, out value)) | ||
| { | ||
| result |= value; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (result == 0) | ||
| { | ||
| result = DefaultChannels; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| // by default, do not include analytic events. | ||
| const PSKeyword DefaultKeywords = (PSKeyword) (0xFFFFFFFFFFFFFFFF & ~(ulong)PSKeyword.UseAlwaysAnalytic); | ||
|
|
||
| /// <summary> | ||
| /// Gets the bitmask of keywords to log. | ||
| /// </summary> | ||
| /// <returns> | ||
| /// A bitmask of PSKeyword values. | ||
| /// <para> | ||
| /// The default value is all keywords other than UseAlwaysAnalytic. | ||
| /// </para> | ||
| /// </returns> | ||
| internal override PSKeyword GetLogKeywords() | ||
| { | ||
| string fileName = Path.Combine(psHomeConfigDirectory, configFileName); | ||
| string values = ReadValueFromFile<string>(fileName, "LogKeywords"); | ||
|
|
||
| PSKeyword result = 0; | ||
| if (!string.IsNullOrEmpty(values)) | ||
| { | ||
| string[] names = values.Split(s_valueSeparators, StringSplitOptions.RemoveEmptyEntries); | ||
|
|
||
| foreach (string name in names) | ||
| { | ||
| if (name.Equals(LogDefaultValue, StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| result = 0; | ||
| break; | ||
| } | ||
|
|
||
| PSKeyword value; | ||
| if (Enum.TryParse<PSKeyword>(name, true, out value)) | ||
| { | ||
| result |= value; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (result == 0) | ||
| { | ||
| result = DefaultKeywords; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| #endif // UNIX | ||
|
|
||
| private T ReadValueFromFile<T>(string fileName, string key) | ||
| { | ||
| fileLock.EnterReadLock(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add final dot.