Skip to content
Merged
Changes from all commits
Commits
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
57 changes: 56 additions & 1 deletion src/libpsl-native/src/nativesyslog.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,65 @@
//! @brief Provides wrappers around the syslog apis to support exporting
//! for PInvoke calls by powershell.
//! These functions are intended only for PowerShell internal use.
//! To view log output in real time
//! On Linux
//! tail -f /var/log/syslog | grep powershell
//! On OSX
//! sudo log stream
//! NOTE: replace powershell with the LogIdentity value when overriding in configuration
#include <syslog.h>
#include <nativesyslog.h>

#if defined(__APPLE__) && defined(__MACH__)

#include <os/log.h>
#include <stdio.h>
static os_log_t _log = NULL;

// This format string ensures the message string for the log statements
// are visible. Using just %s marks them as private and the do not show
// up with log stream.
#define MESSAGE_FORMAT "%{public}s"

// The submodule name to pass to os_log_create.
// The passed in ident value will be used for the category.
// see man os_log_create
#define SUBMODULE_NAME "com.microsoft.powershell"

#endif

//! @brief Native_SysLog is a wrapper around the syslog api.
//! It explicitly passes the message as a parameter to a %s format
//! string since the message may have arbitray characters that can
//! string since the message may have arbitrary characters that can
//! be misinterpreted as format specifiers.
//!
//! @retval none.
extern "C" void Native_SysLog(int32_t priority, const char* message)
{
#if defined(__APPLE__) && defined(__MACH__)
switch (priority)
{
case LOG_EMERG:
case LOG_ALERT:
case LOG_CRIT:
os_log_fault(_log, MESSAGE_FORMAT, message);
break;

case LOG_ERR:
os_log_error(_log, MESSAGE_FORMAT, message);
break;

case LOG_DEBUG:
os_log_debug(_log, MESSAGE_FORMAT, message);
Copy link
Member

Choose a reason for hiding this comment

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

For those different log types, do we need to check whether the type is enabled before calling the log method? What would happen in case the target type is not enabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The check occurs in SysLogProvider.cs. The filters are passed into its constructor by PSSysLogProvider. Both Linux and Mac use the PowerShellProperties.json to define the filters (see JsonConfigFileAccessor in PropertyAccessor.cs)

Copy link
Member

Choose a reason for hiding this comment

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

I don't see the API os_log_type_enabled exposed in this .cpp file, how does SysLogProvider.cs check if a log type is enabled? Does it enable all log types when creating the log object when calling os_log_create?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not needed. Operational events are logged at the default level; which is enabled by default so we'll see the same output we would see in the event log.

https://developer.apple.com/documentation/os/os_log

I'd prefer to filter without interop calls at the risk that someone will change the configuration for powershell at the native layer and we make unneeded interop calls. We can address this later, if it becomes an issue.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the clarification. #Closed

break;

default:
os_log(_log, MESSAGE_FORMAT, message);
break;
}
#else
syslog(priority, "%s", message);
#endif
}

//! @brief Native_OpenLog is a wrapper around the openlog, syslog api.
Expand All @@ -23,13 +70,21 @@ extern "C" void Native_SysLog(int32_t priority, const char* message)
//! @retval none.
extern "C" void Native_OpenLog(const char* ident, int facility)
{
#if defined(__APPLE__) && defined(__MACH__)
_log = os_log_create(SUBMODULE_NAME, ident);
#else
openlog(ident, LOG_NDELAY | LOG_PID, facility);
#endif
}

//! @brief Native_OpenLog is a wrapper around the closelog, syslog api.
//!
//! @retval none.
extern "C" void Native_CloseLog()
{
#if defined(__APPLE__) && defined(__MACH__)
// Nothing to do here now, for now.
#else
closelog();
#endif
}