/// <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); }
internal override void WriteTransferEvent( Guid relatedActivityId, PSEventId eventForOperationalChannel, PSEventId eventForAnalyticChannel, PSKeyword keyword, PSTask task) { }
internal override void ReplaceActivityIdForCurrentThread( Guid newActivityId, PSEventId eventForOperationalChannel, PSEventId eventForAnalyticChannel, PSKeyword keyword, PSTask task) { }
internal static void LogAnalyticVerbose(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, long objectId, long fragmentId, int isStartFragment, int isEndFragment, int fragmentLength, PSETWBinaryBlob fragmentData) { if (provider.IsEnabled(PSLevel.Verbose, keyword)) { string str = BitConverter.ToString(fragmentData.blob, fragmentData.offset, fragmentData.length); str = string.Format(CultureInfo.InvariantCulture, "0x{0}", new object[] { str.Replace("-", "") }); provider.WriteEvent(id, PSChannel.Analytic, opcode, PSLevel.Verbose, task, keyword, new object[] { objectId, fragmentId, isStartFragment, isEndFragment, fragmentLength, str }); } }
/// <summary> /// Initializes a new instance of this class. /// </summary> /// <param name="applicationId">The log identity name used to identify the application in syslog.</param> /// <param name="level">The trace lavel to enable.</param> /// <param name="keywords">The keywords to enable.</param> /// <param name="channels">The output channels to enable.</param> public SysLogProvider(string applicationId, PSLevel level, PSKeyword keywords, PSChannel channels) { // NOTE: This string needs to remain valid for the life of the process since the underlying API keeps // a reference to it. // FUTURE: If logging is redesigned, make these details static or a singleton since there should only be one // instance active. _nativeSyslogIdent = Marshal.StringToHGlobalAnsi(applicationId); NativeMethods.OpenLog(_nativeSyslogIdent, _facility); _keywordFilter = (ulong)keywords; _levelFilter = (byte)level; _channelFilter = (byte)channels; }
/// <summary> /// Logs informational message to the analytic channel /// </summary> /// <param name="id"></param> /// <param name="opcode"></param> /// <param name="task"></param> /// <param name="keyword"></param> /// <param name="args"></param> internal static void LogAnalyticInformational(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
static internal void LogAnalyticVerbose(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
/// <summary> /// Logs informational message to the analytic channel /// </summary> /// <param name="id"></param> /// <param name="opcode"></param> /// <param name="task"></param> /// <param name="keyword"></param> /// <param name="args"></param> internal static void LogAnalyticInformational(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { provider.WriteEvent(id, PSChannel.Analytic, opcode, PSLevel.Informational, task, keyword, args); }
internal static void ReplaceActivityIdForCurrentThread(Guid newActivityId, PSEventId eventForOperationalChannel, PSEventId eventForAnalyticChannel, PSKeyword keyword, PSTask task) { // set the new activity id provider.SetActivityIdForCurrentThread(newActivityId); // Once the activity id is set, write the transfer event WriteTransferEvent(newActivityId, eventForOperationalChannel, eventForAnalyticChannel, keyword, task); }
/// <summary> /// Logs error message to operation channel. /// </summary> /// <param name="id"></param> /// <param name="opcode"></param> /// <param name="task"></param> /// <param name="keyword"></param> /// <param name="args"></param> internal static void LogOperationalError(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { }
// NOTE: There are a number of places where PowerShell code sends analytic events // to the operational channel. This is a side-effect of the custom wrappers that // use flags that are not consistent with the event definition. // To ensure filtering of analytic events is consistent, both keyword and channel // filtering is performed to suppress analytic events. private bool ShouldLog(PSLevel level, PSKeyword keywords, PSChannel channel) { return((_channelFilter & (ulong)channel) != 0 && IsEnabled(level, keywords)); }
internal static IETWTracer GetETWTracer(PSKeyword keyword) => PSETWTracerFactory.tracerLoader != null?PSETWTracerFactory.tracerLoader.GetETWTracer(keyword) : PSETWTracerFactory.EmptyTracer;
/// <summary> /// Determines whether any session is requesting the specified event from the provider. /// </summary> /// <param name="level"></param> /// <param name="keywords"></param> /// <returns></returns> /// <remarks> /// Typically, a provider does not call this method to determine whether a session requested the specified event; /// the provider simply writes the event, and ETW determines whether the event is logged to a session. A provider /// may want to call this function if the provider needs to perform extra work to generate the event. In this case, /// calling this function first to determine if a session requested the event or not, may save resources and time. /// </remarks> internal bool IsEnabled(PSLevel level, PSKeyword keywords) { return etwProvider.IsEnabled((byte)level, (long)keywords); }
static internal void ReplaceActivityIdForCurrentThread(Guid newActivityId, PSEventId eventForOperationalChannel, PSEventId eventForAnalyticChannel, PSKeyword keyword, PSTask task) { }
internal static void ReplaceActivityIdForCurrentThread(Guid newActivityId, PSEventId eventForOperationalChannel, PSEventId eventForAnalyticChannel, PSKeyword keyword, PSTask task) { provider.SetActivityIdForCurrentThread(newActivityId); WriteTransferEvent(newActivityId, eventForOperationalChannel, eventForAnalyticChannel, keyword, task); }
internal virtual IETWTracer GetETWTracer(PSKeyword keyword) => (IETWTracer)null;
/// <summary> /// Writes a log entry. /// </summary> /// <param name="eventId">The event id of the log entry.</param> /// <param name="channel">The channel to log.</param> /// <param name="task">The task for the log entry.</param> /// <param name="opcode">The operation for the log entry.</param> /// <param name="level">The logging level.</param> /// <param name="keyword">The keyword(s) for the event.</param> /// <param name="args">The payload for the log message.</param> public void Log(PSEventId eventId, PSChannel channel, PSTask task, PSOpcode opcode, PSLevel level, PSKeyword keyword, params object[] args) { if (keyword == PSKeyword.UseAlwaysAnalytic) { // Use the 'DefaultKeywords' to work around the default keyword filter. // Note that the PSKeyword argument is not really used in writing SysLog. keyword = PSSysLogProvider.DefaultKeywords; } if (ShouldLog(level, keyword, channel)) { int threadId = Thread.CurrentThread.ManagedThreadId; StringBuilder sb = MessageBuilder; sb.Clear(); // add the message preamble sb.AppendFormat(CultureInfo.InvariantCulture, "({0}:{1:X}:{2:X}) [{3:G}:{4:G}.{5:G}.{6:G}] ", PSVersionInfo.GitCommitId, threadId, channel, eventId, task, opcode, level); // add the message GetEventMessage(sb, eventId, args); NativeMethods.SysLogPriority priority; if ((int)level <= _levels.Length) { priority = _levels[(int)level]; } else { priority = NativeMethods.SysLogPriority.Info; } // log it. NativeMethods.SysLog(priority, sb.ToString()); } }
static internal void LogOperationalInformation(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) { }
/// <summary> /// Writes an event /// </summary> /// <param name="id"></param> /// <param name="channel"></param> /// <param name="opcode"></param> /// <param name="level"></param> /// <param name="task"></param> /// <param name="keyword"></param> /// <param name="args"></param> internal void WriteEvent(PSEventId id, PSChannel channel, PSOpcode opcode, PSLevel level, PSTask task, PSKeyword keyword, params object[] args) { long longKeyword = 0x00; if (keyword == PSKeyword.UseAlwaysAnalytic || keyword == PSKeyword.UseAlwaysOperational) { longKeyword = 0x00; } else { longKeyword = (long)keyword; } EventDescriptor desc = new EventDescriptor((int)id, (byte)PSEventVersion.One, (byte)channel, (byte)level, (byte)opcode, (int)task, longKeyword); etwProvider.WriteEvent(ref desc, args); }
/// <summary> /// Determines whether any session is requesting the specified event from the provider. /// </summary> /// <param name="level"></param> /// <param name="keywords"></param> /// <returns></returns> /// <remarks> /// Typically, a provider does not call this method to determine whether a session requested the specified event; /// the provider simply writes the event, and ETW determines whether the event is logged to a session. A provider /// may want to call this function if the provider needs to perform extra work to generate the event. In this case, /// calling this function first to determine if a session requested the event or not, may save resources and time. /// </remarks> internal bool IsEnabled(PSLevel level, PSKeyword keywords) { return(false); }
/// <summary> /// Gets the value indicating if the specified level and keywords are enabled for logging. /// </summary> /// <param name="level">The PSLevel to check.</param> /// <param name="keywords">The PSKeyword to check.</param> /// <returns>True if the specified level and keywords are enabled for logging.</returns> internal bool IsEnabled(PSLevel level, PSKeyword keywords) { return(((ulong)keywords & _keywordFilter) != 0 && ((int)level <= _levelFilter)); }
internal void WriteEvent(PSEventId id, PSChannel channel, PSOpcode opcode, PSLevel level, PSTask task, PSKeyword keyword, params object[] args) { long keywords = 0L; if ((keyword == PSKeyword.UseAlwaysAnalytic) || (keyword == PSKeyword.UseAlwaysOperational)) { keywords = 0L; } else { keywords = (long) keyword; } System.Diagnostics.Eventing.EventDescriptor eventDescriptor = new System.Diagnostics.Eventing.EventDescriptor((int) id, 1, (byte) channel, (byte) level, (byte) opcode, (int) task, keywords); etwProvider.WriteEvent(ref eventDescriptor, args); }
/// <summary> /// Logs remoting fragment data to verbose channel. /// </summary> /// <param name="id"></param> /// <param name="opcode"></param> /// <param name="task"></param> /// <param name="keyword"></param> /// <param name="objectId"></param> /// <param name="fragmentId"></param> /// <param name="isStartFragment"></param> /// <param name="isEndFragment"></param> /// <param name="fragmentLength"></param> /// <param name="fragmentData"></param> internal static void LogAnalyticVerbose(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, Int64 objectId, Int64 fragmentId, int isStartFragment, int isEndFragment, UInt32 fragmentLength, PSETWBinaryBlob fragmentData) { if (provider.IsEnabled(PSLevel.Verbose, keyword)) { string payLoadData = BitConverter.ToString(fragmentData.blob, fragmentData.offset, fragmentData.length); payLoadData = string.Format(CultureInfo.InvariantCulture, "0x{0}", payLoadData.Replace("-", "")); provider.WriteEvent(id, PSChannel.Analytic, opcode, PSLevel.Verbose, task, keyword, objectId, fragmentId, isStartFragment, isEndFragment, fragmentLength, payLoadData); } }
internal void WriteEvent(PSEventId id, PSChannel channel, PSOpcode opcode, PSLevel level, PSTask task, PSKeyword keyword, params object[] args) { long keywords = 0L; if ((keyword == PSKeyword.UseAlwaysAnalytic) || (keyword == PSKeyword.UseAlwaysOperational)) { keywords = 0L; } else { keywords = (long)keyword; } System.Diagnostics.Eventing.EventDescriptor eventDescriptor = new System.Diagnostics.Eventing.EventDescriptor((int)id, 1, (byte)channel, (byte)level, (byte)opcode, (int)task, keywords); etwProvider.WriteEvent(ref eventDescriptor, args); }
/// <summary> /// Logs error message to operation channel. /// </summary> /// <param name="id"></param> /// <param name="opcode"></param> /// <param name="task"></param> /// <param name="keyword"></param> /// <param name="args"></param> internal static void LogOperationalError(PSEventId id, PSOpcode opcode, PSTask task, PSKeyword keyword, params object[] args) { provider.WriteEvent(id, PSChannel.Operational, opcode, PSLevel.Error, task, keyword, args); }
/// <summary> /// Writes a transfer event mapping current activity id /// with a related activity id /// This function writes a transfer event for both the /// operational and analytic channels /// </summary> /// <param name="relatedActivityId"></param> /// <param name="eventForOperationalChannel"></param> /// <param name="eventForAnalyticChannel"></param> /// <param name="keyword"></param> /// <param name="task"></param> internal static void WriteTransferEvent(Guid relatedActivityId, PSEventId eventForOperationalChannel, PSEventId eventForAnalyticChannel, PSKeyword keyword, PSTask task) { provider.WriteEvent(eventForOperationalChannel, PSChannel.Operational, PSOpcode.Method, PSLevel.Informational, task, PSKeyword.UseAlwaysOperational); provider.WriteEvent(eventForAnalyticChannel, PSChannel.Analytic, PSOpcode.Method, PSLevel.Informational, task, PSKeyword.UseAlwaysAnalytic); }