/// <summary>Returns the JournalMessage.</summary> public void Dispose() { Clear(); if (s_cachedMessage == null || (this._data.Count > s_cachedMessage._data.Count)) // Prefer caching longer _data { s_cachedMessage = this; } }
internal static JournalMessage Get(bool isEnabled) { JournalMessage message = s_cachedMessage; if (message == null) { message = new JournalMessage(); } else { s_cachedMessage = null; } message._isEnabled = isEnabled; return(message); }
/// <summary>Obtain a cleared JournalMessage. The Message must be Disposed to return it.</summary> public static JournalMessage GetMessage() { return(JournalMessage.Get(IsSupported)); }
/// <summary> /// Submit a log entry to the journal. /// </summary> public static unsafe LogResult Log(LogFlags flags, JournalMessage message) { Socket socket = GetJournalSocket(); if (socket == null) { if (s_isSupported.Value) { return(LogResult.NotAvailable); } else { return(LogResult.NotSupported); } } if (message.IsEmpty) { return(LogResult.Success); } int priority = (int)flags & 0xf; if (priority != 0) { message.Append(JournalFieldName.Priority, priority - 1); } if (((flags & LogFlags.DontAppendSyslogIdentifier) == LogFlags.None) && SyslogIdentifier != null) { message.Append(JournalFieldName.SyslogIdentifier, SyslogIdentifier); } List <ArraySegment <byte> > data = message.GetData(); int dataLength = data.Count; if (dataLength > MaxIovs) { // We should handle this the same way as EMSGSIZE, which we don't handle atm. ErrorWhileLogging("size exceeded"); return(LogResult.Size); } Span <IOVector> iovs = stackalloc IOVector[dataLength]; Span <GCHandle> handles = stackalloc GCHandle[dataLength]; for (int i = 0; i < data.Count; i++) { handles[i] = GCHandle.Alloc(data[i].Array, GCHandleType.Pinned); iovs[i].Base = handles[i].AddrOfPinnedObject(); iovs[i].Length = new IntPtr(data[i].Count); } int sendmsgFlags = 0; if ((flags & LogFlags.DropWhenBusy) != 0) { sendmsgFlags |= MSG_DONTWAIT; } LogResult result = LogResult.Success; fixed(IOVector *pIovs = &MemoryMarshal.GetReference(iovs)) { bool loop; do { loop = false; msghdr msg; msg.msg_iov = pIovs; msg.msg_iovlen = (SizeT)dataLength; int rv = sendmsg(socket.Handle.ToInt32(), &msg, sendmsgFlags).ToInt32(); if (rv < 0) { int errno = Marshal.GetLastWin32Error(); if (errno == EINTR) { loop = true; } else if (errno == EAGAIN) { result = LogResult.Busy; } else { result = LogResult.UnknownError; ErrorWhileLogging($"errno={errno}"); } } } while (loop); } for (int i = 0; i < handles.Length; i++) { handles[i].Free(); } return(result); }