Last active
September 26, 2018 05:12
-
-
Save teyc/c1bb25c6f669ad626d1b to your computer and use it in GitHub Desktop.
Pipes objects to Seq
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// How to debug your powershell scripts by piping the intermediate results to Seq | |
// 1. Compile this into WriteSeq.dll | |
// 2. > Import-Module .\WriteSeq.dll | |
// 3. > Get-ChildItems C:\ | ? { $_.Name -ilike { "*Program*" } | Write-Seq | Format-Table | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Management.Automation; | |
using System.Net; | |
using System.Reflection; | |
using System.Runtime.Serialization; | |
using System.Runtime.Serialization.Json; | |
using System.Text; | |
using System.Threading; | |
namespace WriteSeq | |
{ | |
[Cmdlet("Write", "Seq",ConfirmImpact = ConfirmImpact.Low)] | |
public class WriteSeq : PSCmdlet | |
{ | |
private string _seqUrl = "http://localhost:5341"; | |
private readonly List<Event> _events = new List<Event>(); | |
[Parameter(ValueFromPipeline = true, DontShow = true)] | |
public PSObject[] InputObject { get; set; } | |
[Parameter(Mandatory = false)] | |
public string ApiKey { get; set; } | |
[Parameter(Mandatory = false, HelpMessage = "The url of the Seq server. By default it is http://localhost:5341")] | |
public string SeqUrl | |
{ | |
get { return _seqUrl; } | |
set { _seqUrl = value.TrimEnd('/'); } | |
} | |
protected override void ProcessRecord() | |
{ | |
foreach (var o in InputObject) | |
{ | |
_events.Add(ToEvent(o)); | |
WriteObject(o); | |
} | |
} | |
protected override void EndProcessing() | |
{ | |
PostRawEvents(_events); | |
} | |
private Event ToEvent(PSObject o) | |
{ | |
return new Event() | |
{ | |
MessageTemplate = o.ToString(), | |
Level = "Information", | |
Properties = o.Properties | |
.ToDictionary(p => p.Name, p => (object) p.Value.ToString()) | |
}; | |
} | |
private void PostRawEvents(IEnumerable<Event> e) | |
{ | |
var events = new RawEvents() | |
{ | |
Events = e.ToArray() | |
}; | |
using (var stream = new MemoryStream()) | |
{ | |
// .NET 4 | |
//new DataContractJsonSerializer(typeof(RawEvents)).WriteObject(stream, events); | |
// .NET 45 | |
new DataContractJsonSerializer(typeof(RawEvents), new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true}).WriteObject(stream, events); | |
var buffer = stream.GetBuffer(); | |
WriteDebug(Encoding.UTF8.GetString(buffer)); | |
var requestUriString = SeqUrl + "/api/events/raw"; | |
if (!string.IsNullOrWhiteSpace(ApiKey)) | |
{ | |
requestUriString += "?apiKey=" + ApiKey; | |
} | |
var request = (HttpWebRequest) WebRequest.Create(requestUriString); | |
request.ContentType = "application/json"; | |
request.Method = WebRequestMethods.Http.Post; | |
request.ContentLength = buffer.Length; | |
request.KeepAlive = false; | |
request.Timeout = Timeout.Infinite; | |
request.ProtocolVersion = HttpVersion.Version10; | |
using (var requestStream = request.GetRequestStream()) | |
{ | |
requestStream.Write(buffer, 0, buffer.Length); | |
} | |
var response = request.GetResponse(); | |
using (var responseStream = response.GetResponseStream()) | |
{ | |
new StreamReader(responseStream).ReadToEnd(); | |
} | |
}; | |
} | |
} | |
[DataContract] | |
internal class RawEvents | |
{ | |
[DataMember] | |
public Event[] Events { get; set; } | |
} | |
[DataContract] | |
internal class Event | |
{ | |
[DataMember] | |
public string Timestamp | |
{ | |
get { return DateTimeOffset.Now.ToString("yyyy-MM-ddThh:mm:ss.fff%K"); } | |
set { } | |
} | |
[DataMember] | |
public string Level { get; set; } | |
[DataMember] | |
public string MessageTemplate { get; set; } | |
[DataMember] | |
public IDictionary<string, object> Properties { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment