{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/57541352","id":57541352,"diff_hunk":"@@ -0,0 +1,377 @@\n+﻿# DiagnosticSource Users Guide\n+\n+This document describes DiagnosticSource, a simple module that allows code \n+to be instrumented for production-time logging of **rich data payloads** for \n+consumption **within the process** that was instrumented.   At runtime consumers\n+can **dynamically discover** data sources and subscribe to the ones of interest.  \n+\n+In addition to background on how the class works, this document also covers \n+[naming conventions](#naming-conventions) and [best practices](#best-practices) when \n+instrumenting code.     \n+\n+-------------------------------------------\n+## Relationship to Other Logging Facilities \n+\n+In addition to DiagnosticSource, there are two other logging systems provided by Microsoft:\n+\n+  1. EventSource [docs](https://msdn.microsoft.com/en-us/library/system.diagnostics.tracing.eventsource(v=vs.110).aspx) \n+\t and [src](https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs).\n+\t EventSource has been available since V4.5 of the .NET Runtime and is what is used\n+\t to instrument the runtime itself.   It is designed to be fast and to be strongly\n+\t typed (payloads are typed, named properties), and to interface with OS logging\n+\t infrastructure like Event Tracing for Windows [(ETW)](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363668(v=vs.85).aspx)\n+\t or [LTTng](http://lttng.org/) on Linux.   \n+\n+  2. ILogger [src](https://github.com/aspnet/logging).  A number of popular 3rd party \n+     formatted string logging systems for .NET have been built including NLog SeriLog\n+\t and Log4Net.    The ILogger Nuget package is designed to 'wrap' any of these and \n+\t hide from the instrumentation code which exact logging system is being used.   Using\n+\t this wrapper makes the most sense if your goal is to 'plug into' a logging pipeline\n+\t that assumes on of these logging systems.   \n+  \n+DiagnosticSource has more architectural similarity to EventSource.  The main difference\n+is that EventSource assumes that the data being logged will **leave the process** and thus\n+requires that **only serializable data** be logged.   However DiagnosticSource was designed\n+to allow in process tools to get at very rich data.   Because the consumer is assumed to be\n+within the same process, non-serializable types (e.g. HttpResponseMessage or HttpContext)\n+can be passed, which gives the consumer a lot of potential data to work with.    \n+\n+As explained in [Bridge to EventSource](bridge-to-eventSource), there is a bridge that\n+pipes information from DiagnosticSource's to an EventSource.   Thus EventSource\n+consumers can get at all DiagnosticSource events.    While the data payloads from \n+DiagnosticSource can't in general be passed through to the EventSource (because they are \n+not serializable), there is a mechanism in the bridge that consumers can specify which fields\n+(which are serializable) from the DiagnosticSource payload should be passed\n+along to the EventSource.  \n+\n+What this means is that in general it is not necessary to instrument a code site multiple\n+times.   By instrumenting with Diagnostic source, both clients that need the rich data\n+(and thus use DiagnosticListener) as well as any consumers using EventListeners \n+(or OS facilities like ETW)) can get at the data.  \n+\n+----------------------------------------\n+## Instrumenting with DiagnosticSource/DiagnosticListener\n+\n+Perhaps surprisingly, the heart of DiagnosticSource logging architecture is is not the\n+DiagnositicSource class but rather the DiagnositicListener class which 'receives' the \n+events.    This is because the DiagnositicSource type is just an abstract base class\n+that defines the methods needed to actually log events.    It is the  DiagnositicListener\n+which holds all the actual implementation.\n+\n+Thus the first step in instrumenting code with DiagnosticSource is to create a \n+DiagnosticListener.   For example\n+\n+```C#\n+    private static DiagnositicSource httpLogger = new DiagnositicListener(\"System.Net.Http\");\n+```\n+Notice that httpLogger is typed as a DiagnositicSource.    This is because this code\n+only cares about writing events and thus only cares about the  DiagnositicSource methods that\n+the DiagnosticListener implements.   DiagnositicListeners are given names when they are created\n+and this name should be the name of logical grouping of related events (typically the component).\n+Later this name is used to find the Listener and subscribe to any of its events.  \n+\n+Once you have an instance of a DiagnositicSource, logging is very straightforward.  The\n+interface consists of only two methods.  \n+\n+```C#\n+\tbool IsEnabled(string name)\n+\tvoid Write(string name, object value);\n+```\n+\n+A typical call site will look like\n+\n+```C#\n+\tif (httpLogger.IsEnabled(\"RequestStart\"))\n+\t\thttpLogger.Write(\"RequestStart\", new { Url=\"http://clr\", Request=aRequest });\n+```\n+\n+Already some of the architectural elements are being exposed namely\n+\n+\t1. Every event has a string name (e.g. Request Start), and exactly one object as a payload.\n+\t2. If you need to send more than one item, you can do so by creating a object with all information\n+\t   in it as properties.   CSharp's [anonymous type](https://msdn.microsoft.com/en-us/library/bb397696.aspx)\n+\t   feature is typically used to create a type to pass 'on the fly', and makes this scheme very\n+\t   convenient.     \n+\t3. At the instrumentation site, you must guard the call to 'Write' with an 'IsEnabled' check on \n+       the same event name.   Without this check, even when the instrumentation is inactive, the rules\n+\t   of the C# language require all the work of creating the payload object and calling 'Write' to be \n+\t   done, even though nothing is actually listening for the data. By guarding the 'Write' call, we \n+\t   make it efficient when the source is not enabled.   \n+\n+### Creating DiagnosticSources (Actually DiagnosticListeners)\n+\t   \n+The code above assumes there is an DiagnosticSource called 'mySource'.   Perhaps confusingly you \n+make a DiagnosticSource by creating DiagnosticListener\n+\n+\tstatic DiagnosticSource mySource = new DiagnosticListener(\"System.Net.Http\");\n+\n+Basically a DiagnosticListener is a named place where a source sends its information (events).  \n+From an implementation point of view, DiagnosticSource is a abstract class that has the two\n+instrumentation methods, and DiagnosticListener is something that implements that abstract class.\n+Thus every DiagnosticListener is a DiagnosticSource.   \n+\n+DiagnosticListener have a name, which is used to represent the component associated with the event.\n+Thus the event names only need to be unique within a component.  \n+\n+----------------------------------------\n+## Best Practices\n+\n+### Naming Conventions\n+\n+#### DiagnositicListener Names\n+\n+ * CONSIDER - the likely scenarios for USING information when deciding how may \n+   DiagnositicListener to have and the events in each.   Keep in mind that it is **very easy\n+   and efficient** to filter all the events in a particular listener so ideally the \n+   most important scnearios involve turning in whole listners.    You may need to split\n+   a source into multiple smaller ones to achieve this and this is OK.   For example There\n+   are both incomming Http request and outgoing Http requests and you may only need one \n+   or the other, so having a System.Net.Http.Incomming and System.Net.Http.OutGoing for\n+   each sub-case is good.  \n+\n+ * CONSIDER -  the likely volume of events.   High volume events may deserve their own\n+   DiagnositicListener.   You don't really want to mix high volume and low volume events\n+   in the same listener unless they both support the same scenario.   It is OK however to\n+   put several **low volume** events in a 'miscelaneous' listener, even if they support different \n+   scenarios if it simplifies things enough.\n+\n+ * DO - Consider the scenario when picking the name for the DiagnositicListener.  Often This\n+   name is the component in which the DiagnositicListener lives, but **usage scnearios trump\n+   component naming**.   You want it to be the case that users can correctly guess which\n+   listeners to activate knowing just their scneario.   \n+   \n+ * DO - Make the name for the DiagnositicListeners **globally unique**.   This is Typically\n+   done by making the first part of the name the component (e.g. System.Net.Http) \n+\n+ * DO - Use dots '.' to create multi-part names.   This works well if the name is a Name\n+   of a component (which uses dots).  \n+ \n+ * DO NOT - name the listener after the Listener (thus something like System.Net.HttpDIagnosticListener\n+   is bad).   \n+\n+#### EventNames \n+\n+ * DO - keep the names reasonably short (< 16 characters).   Keep in mind that that event names \n+   are already qualified by the Listener so the name only needs to be unique within a listener. \n+   Short names make the 'IsEnabled' faster.  \n+\n+ * DO - use the 'Start' and 'Stop' suffixes for events that define an interval of time.  For example   \n+   Naming one event 'RequestStart' and the another 'ReqeustStop' is good because tools can use the\n+   convention to determine that the time interval betweeen them is interesting.  \n+\n+### payloads\n+\n+  * DO use the anonymous type syntax 'new { property1 =value1 ...}' as the default way to pass \n+   a payload *even if there is only one data element*.   This makes adding more data later easy\n+   and compatible.  \n+\n+  * CONSIDER - if you have and event that is so frequent that the performance of the logging is \n+   a important consideration,  **and** you have only one data item **and** it is ulikely that \n+   you will ever have more data to pass to the event, **and** and the data item is a normal class\n+   (not a value type) **then** you save some cost by simply by passing the data object directly\n+   without using an anonymous type wrapper.   \n+\n+  * DO - use standard names for particular payload items.   (TODO add the existing ones).\n+  \n+### Other Conventions \n+\n+ * DO - always enclose the Write() call in a call to 'IsEnabled' for the same event name.  Otherwise\n+   alot of setup logic will be called even if there is nothing listening for the event.\n+\n+ * DO NOT - make the DiagnositicListener public.   There is no need to as subscribers will \n+  use the AllListerner property to hook up. \n+\n+----------------------------------------\n+## Consuming Data with DiagnosticListener. \n+\n+Up until now, this guide has focused on how to instrument code to generate logging\n+information.   In this section we focus on subscribing and decoding of that information.\n+\n+### Discovery of DiagnosticListeners.   \n+\n+The first step in receiving events is to discover which DiagnosticListeners you are\n+interested in.    While it is possible to discover DiagnosticListeners  at compile time \n+by referencing static variables (e.g. like the httpLogger in the previous example), this\n+is typically not flexible enough.   \n+\n+Instead DiagnosticListener supports a way of discovering DiagnosticListener that is\n+active in the system at runtime.   The API to accomplish this is the 'AllListeners' \n+IObservable<DiagnosticListener>.     \n+\n+The IObservable interface is the 'callback' version of the IEnumerable interface.   You can learn \n+more about it at the [Reactive Extensions Site](https://msdn.microsoft.com/en-us/data/gg577609.aspx).\n+In a nutshell, you have an object called an IOberserver which has three callbacks, OnNext, OnComplete\n+and OnError, and an IObservable has single method called 'Subscribe' which gets passed one of these\n+Observers.   Once connected, the Observer get callback (mostly OnNext callbacks) when things \n+happen.   By including the System.Reactive.Core Nuget package, you can get a bunch of useful \n+Extensions that make using IObservable nice.   \n+\n+A typical use of the AllListeners static property looks like this:\n+\n+```C#\n+\t// We are using  to turn a Action<DiagnosticListener> into a IObserver<DiagnosticListener>  \n+\tstatic IDisposeable listenerSubscription = DiagnosticListener.AllListeners.Subscribe(delegate (DiagnosticListener listener)\n+\t{\n+\t\t// We get a callback of every Diagnostics Listener that is active in the system (past present or future)\n+\t\tif (listener.Name == \"System.Net.Http\")\n+\t\t{\n+\t\t\t// Here is where we put code to subscribe to the Listener. \n+\t\t}\n+\t});\n+\n+\t// Typically you leave the listenerSubscription subscription active forever.   \n+\t// However when you no longer want your callback to be called, you can \n+\t// call listenerSubscription.Dispose() to cancel your subscription to the IOberservable.  \n+```\n+\n+This code basically creates a callback delegate and using the 'AllListeners.Subscribe' method requests\n+that that delegate be called for every active DiagnosticListener in the system.   Typically you inspect\n+the name of the listener and based on that, decide whether to subscribe to listener or not.  The\n+code above is looking for our 'System.Net.Http' listener that we created previously.\n+\n+Like all calls to Subscribe, this one returns a IDisposable that represents the subscription itself.\n+Callbacks will continue to happen as long as nothing calls Dispose() on this subscription object.   \n+The above code never calls it, so it will receive callbacks forever.  \n+\n+It is important to note that when you Subscribe to AllListeners, you get a callback for ALL ACTIVE DiagnositicListeners.\n+Thus upon subscribing you get a furry of callbacks of all existing DiagnositicListeners but as new ones\n+are created, you get a callback for those as well.   Thus you get a complete list of everything it is possible\n+to subscribe to.  \n+\n+Finally, note that the code above is taking advantage of convenience functionality in the System.Reactive.Core\n+library.   The DiagnosticListener.AllListeners.Subscribe method actually requires that it be passed\n+an IOberserver<DiagnosticListener>, which is a class that has three callbacks (OnNext, OnError, OnComplete),\n+but we passed it a Action<DiagnosticListener>.   The magic that makes this work is an extension method\n+in System.Reactive.Core that takes the Action and from it makes a IOberserver (called AnonymousObserver) \n+which calls the Action on its OnNext callback.   This glue is what makes the code concise.  \n+\n+#### Subscribing to DiagnositicListeners\n+\n+A DiagnositicListener implements the IObservable<KeyValuePair<string, object>> interface, so you can\n+call 'Subscribe' on it as well.  Thus we can fill out the previous example a bit \n+\n+```C#\n+\tstatic IDisposeable listenerSubscription = DiagnosticListener.AllListeners.Subscribe(delegate (DiagnosticListener listener)\n+\tstatic IDisposable networkSubscription = null;\n+\t{\n+\t\tif (listener.Name == \"System.Net.Http\")\n+\t\t{\n+\t\t\tlock(allListeners)\n+\t\t\t{\n+\t\t\t\tif (networkSubscription != null)\n+\t\t\t\t\tnetworkSubscription.Dispose();\n+\n+\t\t\t\tnetworkSubscription = listener.Subscribe((KeyValuePair<string, object> evnt) => \n+\t\t\t\t\tConsole.WriteLine(\"From Listener {0} Received Event {1} with payload {2}\", \n+\t\t\t\t\tnetworkListener.Name, evnt.Key, evnt.Value.ToString()));\n+\t\t\t}\n+\t\t}\n+\t});\n+\n+\t// At some point you may wish to dispose the networkSubscription.\n+```\n+\n+In this example after finding the 'System.Net.Http' DiagnositicListener, we create an action that \n+prints out the name of the listener, event, and payload.ToString().   Notice a few things\n+\n+   1. DiagnositicListener implement IObservable<KeyValuePair<string, object>>.   This means \n+      on each callback we get a KeyValuePair.  The key of this pair is the name of the event\n+\t  and the value is the payload object.  In the code above we simply log this information\n+\t  to the Console.  \n+   2. We keep track of our subscriptions to the DiagnositicListeners.   In this case we have\n+      a networkSubscription variable that remembers this, and we get another 'creation' we\n+\t  unsubscribe the previous listener and subscribe to the new one.  \n+   3. We use locks.   The DiagnositicSource/DiagnositicListener code is thread safe, but the \n+      callback code also needs to be threadsafe.   It is possible that two DiagnositicListener \n+\t  with the same name are creates at the same time (although that is a bit unexpected), so\n+\t  to avoid races we do update of our shared variables under the protection of a lock.  ","path":"src/System.Diagnostics.DiagnosticSource/src/DiagnosticSourceUsersGuide.md","position":287,"original_position":287,"commit_id":"7827821f3b8a0a715b1b75eaf8558603d98b95d4","original_commit_id":"7827821f3b8a0a715b1b75eaf8558603d98b95d4","user":{"login":"stephentoub","id":2642209,"avatar_url":"https://avatars.githubusercontent.com/u/2642209?v=3","gravatar_id":"","url":"https://api.github.com/users/stephentoub","html_url":"https://github.com/stephentoub","followers_url":"https://api.github.com/users/stephentoub/followers","following_url":"https://api.github.com/users/stephentoub/following{/other_user}","gists_url":"https://api.github.com/users/stephentoub/gists{/gist_id}","starred_url":"https://api.github.com/users/stephentoub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephentoub/subscriptions","organizations_url":"https://api.github.com/users/stephentoub/orgs","repos_url":"https://api.github.com/users/stephentoub/repos","events_url":"https://api.github.com/users/stephentoub/events{/privacy}","received_events_url":"https://api.github.com/users/stephentoub/received_events","type":"User","site_admin":false},"body":"Nit: update => updates","created_at":"2016-03-28T03:02:33Z","updated_at":"2016-03-28T03:02:33Z","html_url":"https://github.com/dotnet/corefx/pull/7286#discussion_r57541352","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/7286","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/57541352"},"html":{"href":"https://github.com/dotnet/corefx/pull/7286#discussion_r57541352"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7286"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/7286","id":64273074,"html_url":"https://github.com/dotnet/corefx/pull/7286","diff_url":"https://github.com/dotnet/corefx/pull/7286.diff","patch_url":"https://github.com/dotnet/corefx/pull/7286.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/7286","number":7286,"state":"open","locked":false,"title":"Doc checkin.   Added NewDiagnosticListener","user":{"login":"vancem","id":8459414,"avatar_url":"https://avatars.githubusercontent.com/u/8459414?v=3","gravatar_id":"","url":"https://api.github.com/users/vancem","html_url":"https://github.com/vancem","followers_url":"https://api.github.com/users/vancem/followers","following_url":"https://api.github.com/users/vancem/following{/other_user}","gists_url":"https://api.github.com/users/vancem/gists{/gist_id}","starred_url":"https://api.github.com/users/vancem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vancem/subscriptions","organizations_url":"https://api.github.com/users/vancem/orgs","repos_url":"https://api.github.com/users/vancem/repos","events_url":"https://api.github.com/users/vancem/events{/privacy}","received_events_url":"https://api.github.com/users/vancem/received_events","type":"User","site_admin":false},"body":"Added the DiagnosticSourceUsersGuide.md as well as hyperlinks in the\r\nsource code to get at it.\r\n\r\nAlso added a new event the fires when a new DiagnosticListener gets\r\ncreated.  This allows subscribers to simply look at this event\r\nand only after receiving it decide whether they should subscribe.","created_at":"2016-03-27T19:18:40Z","updated_at":"2016-03-28T03:02:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d5ebf18b4c8f5d4cddc69d04dddfee0f70aeba98","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/7286/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/7286/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/7286/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/7827821f3b8a0a715b1b75eaf8558603d98b95d4","head":{"label":"vancem:DiagnosticSourceDocs","ref":"DiagnosticSourceDocs","sha":"7827821f3b8a0a715b1b75eaf8558603d98b95d4","user":{"login":"vancem","id":8459414,"avatar_url":"https://avatars.githubusercontent.com/u/8459414?v=3","gravatar_id":"","url":"https://api.github.com/users/vancem","html_url":"https://github.com/vancem","followers_url":"https://api.github.com/users/vancem/followers","following_url":"https://api.github.com/users/vancem/following{/other_user}","gists_url":"https://api.github.com/users/vancem/gists{/gist_id}","starred_url":"https://api.github.com/users/vancem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vancem/subscriptions","organizations_url":"https://api.github.com/users/vancem/orgs","repos_url":"https://api.github.com/users/vancem/repos","events_url":"https://api.github.com/users/vancem/events{/privacy}","received_events_url":"https://api.github.com/users/vancem/received_events","type":"User","site_admin":false},"repo":{"id":41119686,"name":"corefx","full_name":"vancem/corefx","owner":{"login":"vancem","id":8459414,"avatar_url":"https://avatars.githubusercontent.com/u/8459414?v=3","gravatar_id":"","url":"https://api.github.com/users/vancem","html_url":"https://github.com/vancem","followers_url":"https://api.github.com/users/vancem/followers","following_url":"https://api.github.com/users/vancem/following{/other_user}","gists_url":"https://api.github.com/users/vancem/gists{/gist_id}","starred_url":"https://api.github.com/users/vancem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vancem/subscriptions","organizations_url":"https://api.github.com/users/vancem/orgs","repos_url":"https://api.github.com/users/vancem/repos","events_url":"https://api.github.com/users/vancem/events{/privacy}","received_events_url":"https://api.github.com/users/vancem/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/vancem/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":true,"url":"https://api.github.com/repos/vancem/corefx","forks_url":"https://api.github.com/repos/vancem/corefx/forks","keys_url":"https://api.github.com/repos/vancem/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vancem/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vancem/corefx/teams","hooks_url":"https://api.github.com/repos/vancem/corefx/hooks","issue_events_url":"https://api.github.com/repos/vancem/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/vancem/corefx/events","assignees_url":"https://api.github.com/repos/vancem/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/vancem/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/vancem/corefx/tags","blobs_url":"https://api.github.com/repos/vancem/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vancem/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vancem/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/vancem/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vancem/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/vancem/corefx/languages","stargazers_url":"https://api.github.com/repos/vancem/corefx/stargazers","contributors_url":"https://api.github.com/repos/vancem/corefx/contributors","subscribers_url":"https://api.github.com/repos/vancem/corefx/subscribers","subscription_url":"https://api.github.com/repos/vancem/corefx/subscription","commits_url":"https://api.github.com/repos/vancem/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/vancem/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/vancem/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/vancem/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/vancem/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/vancem/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vancem/corefx/merges","archive_url":"https://api.github.com/repos/vancem/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vancem/corefx/downloads","issues_url":"https://api.github.com/repos/vancem/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/vancem/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/vancem/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/vancem/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vancem/corefx/labels{/name}","releases_url":"https://api.github.com/repos/vancem/corefx/releases{/id}","deployments_url":"https://api.github.com/repos/vancem/corefx/deployments","created_at":"2015-08-20T21:27:34Z","updated_at":"2016-01-15T22:13:48Z","pushed_at":"2016-03-27T19:18:20Z","git_url":"git://github.com/vancem/corefx.git","ssh_url":"git@github.com:vancem/corefx.git","clone_url":"https://github.com/vancem/corefx.git","svn_url":"https://github.com/vancem/corefx","homepage":"http://dotnet.github.io/core/","size":60942,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"62e4989c3e150729e7c5a1efde6cb67b0dc3af62","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","deployments_url":"https://api.github.com/repos/dotnet/corefx/deployments","created_at":"2014-11-06T23:42:48Z","updated_at":"2016-03-27T23:21:18Z","pushed_at":"2016-03-28T02:53:05Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/","size":82796,"stargazers_count":9380,"watchers_count":9380,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2203,"mirror_url":null,"open_issues_count":944,"forks":2203,"open_issues":944,"watchers":9380,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7286"},"html":{"href":"https://github.com/dotnet/corefx/pull/7286"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/7286"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/7286/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7286/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7286/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/7827821f3b8a0a715b1b75eaf8558603d98b95d4"}}}}