Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
479559d
script to generate resx file and event id resource lookup class from …
dantraMSFT Oct 13, 2017
ebfbdcf
Include the name of the manifest file in the resx and C# header comment
dantraMSFT Oct 13, 2017
536eb44
Initial version of the ETW manifest
dantraMSFT Oct 13, 2017
36c25c8
Initial draft of LogProvider for SysLog
dantraMSFT Oct 13, 2017
4e23d84
Minor updates to code gen and exclude gen\EventResource.cs from build
dantraMSFT Oct 14, 2017
e8f138e
logging to syslog enabled - Remove duplicate PSEtwlog class and use …
dantraMSFT Oct 14, 2017
aff9e61
Implement level, channel, and keyword filtering
dantraMSFT Oct 15, 2017
b529cba
Enable PowerShellProperties.json support for linux logging
dantraMSFT Oct 16, 2017
ffb7a88
Fix syslog ident paramter - was using hard-coded string instead of co…
dantraMSFT Oct 17, 2017
31f20e4
Fix build break
dantraMSFT Oct 17, 2017
3db6101
Fix build break
dantraMSFT Oct 17, 2017
1dfb014
address PR feedback
dantraMSFT Oct 20, 2017
731c5e1
Fix stale property reference
dantraMSFT Oct 20, 2017
c8372e8
PR feedback
dantraMSFT Oct 24, 2017
9e4465a
Generate resx with ASCII encoding.
dantraMSFT Oct 24, 2017
c875f8d
PR feedback.
dantraMSFT Oct 25, 2017
99cf86d
Use the right OrdinalIgnoreCase instance.
dantraMSFT Oct 25, 2017
89782f3
Update comments for GitCommitId and use explicit private for MissingE…
dantraMSFT Oct 26, 2017
e20ca59
Regenerate to include explicit private scoping of MissingEventIdResou…
dantraMSFT Oct 26, 2017
e7901fe
Remove inadverntant change.
dantraMSFT Oct 26, 2017
4e04118
Remove GitCommitId hash code logic and log the id raw with each log e…
dantraMSFT Oct 27, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions src/System.Management.Automation/CoreCLR/CorePsStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -783,29 +783,6 @@ public static Guid GetActivityId()
}
}

internal static class PSEtwLog
{
static internal void LogAnalyticError(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void LogAnalyticWarning(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void LogAnalyticVerbose(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword,
Int64 objectId,
Int64 fragmentId,
int isStartFragment,
int isEndFragment,
UInt32 fragmentLength,
PSETWBinaryBlob fragmentData)
{ }
static internal void LogAnalyticVerbose(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void SetActivityIdForCurrentThread(Guid newActivityId) { }
static internal void LogOperationalVerbose(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void LogOperationalWarning(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void ReplaceActivityIdForCurrentThread(Guid newActivityId, PSEventId eventForOperationalChannel, PSEventId eventForAnalyticChannel, PSKeyword keyword, PSTask task) { }
static internal void LogOperationalError(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void LogOperationalError(PSEventId id, PSOpcode opcode, PSTask task, LogContext logContext, string payLoad) { }
static internal void LogAnalyticInformational(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void LogOperationalInformation(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
}

public enum PowerShellTraceTask
{
/// <summary>
Expand Down
616 changes: 616 additions & 0 deletions src/System.Management.Automation/CoreCLR/EventResource.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
<Compile Remove="utils\perfCounters\PSPerfCountersMgr.cs" />
<Compile Remove="gen\CoreMshSnapinResources.cs" />
<Compile Remove="gen\ErrorPackageRemoting.cs" />
<Compile Remove="gen\EventResource.cs" />

<EmbeddedResource Remove="resources\CoreMshSnapinResources.resx" />
<EmbeddedResource Remove="resources\ErrorPackageRemoting.resx" />
Expand Down
195 changes: 195 additions & 0 deletions src/System.Management.Automation/engine/PropertyAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Threading;

using System.Management.Automation;
using System.Management.Automation.Internal;
using Microsoft.Win32;

using Newtonsoft.Json;
Expand Down Expand Up @@ -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'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

/// </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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

/// </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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, it would help if you provided a single feedback indicating DOC comments are missing periods at the end of sentences instead of pointing out each one individually. It makes the feedback somewhat tedious to weed through. Thanks.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I was surprised that sometimes I saw a dot in the XML commentary, so I thought it was just a few typos.

/// <para>
/// The default value is PSChannel.Operational
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

/// </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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add final dot.

/// </para>
/// </returns>
internal abstract PSKeyword GetLogKeywords();

#endif // UNIX
#endregion // Interface Methods
}

Expand Down Expand Up @@ -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");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, why don't we want the identity name to always be "powershell" or "pwsh"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overriding the name allows side by side instances to be distinguished from each other in the log.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense. Thanks!


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[] {' ', ',', '|'};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could go in System.Management.Automation.Utils.Separators - it helps reuse to have a common place arrays like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any inherit benefit in sharing this constant. It simply introduces unnecessary/unintended coupling. ON the other hand, if there's an existing pattern that this should follow; I'm happy to look at it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more of a meta benefit - folks create arrays like this all over the place, sometimes in a loop.

People copy patterns, so if you follow the pattern, others will too. If you don't, they might follow your pattern - and in the new use case, it might be a bad choice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left it encapsulated for now; I consider it a private implementation detail until we have a use case for sharing it.


/// <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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace System.Management.Automation.Internal
/// <summary>
/// Defines enumerations for the keywords
/// </summary>
[Flags]
internal enum PSKeyword : ulong
{
Runspace = 0x1,
Expand Down Expand Up @@ -194,6 +195,7 @@ internal enum PSEventId : int
/// <summary>
/// Defines enumerations for channels
/// </summary>
[Flags]
internal enum PSChannel : byte
{
Operational = 0x10,
Expand Down
Loading