Skip to content

Instantly share code, notes, and snippets.

@teyc
Last active September 26, 2018 05:12
Show Gist options
  • Save teyc/c1bb25c6f669ad626d1b to your computer and use it in GitHub Desktop.
Save teyc/c1bb25c6f669ad626d1b to your computer and use it in GitHub Desktop.
Pipes objects to Seq
// 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