Code Monkey home page Code Monkey logo

applicationinsights-php's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

applicationinsights-php's Issues

Getting "'Client error: 400" when using any example on the home page.

The error comes from Guzzle. Here is a trace:

#0 ...\vendor\guzzlehttp\promises\src\Promise.php(201): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response))
#1 ...\vendor\guzzlehttp\promises\src\Promise.php(154): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), Array)
#2 ...\vendor\guzzlehttp\promises\src\TaskQueue.php(61): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
#3 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlMultiHandler.php(96): GuzzleHttp\Promise\TaskQueue->run()
#4 ...\vendor\guzzlehttp\guzzle\src\Handler\CurlMultiHandler.php(123): GuzzleHttp\Handler\CurlMultiHandler->tick()
#5 ...\vendor\guzzlehttp\promises\src\Promise.php(242): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
#6 ...\vendor\guzzlehttp\promises\src\Promise.php(219): GuzzleHttp\Promise\Promise->invokeWaitFn()
#7 ...\vendor\guzzlehttp\promises\src\Promise.php(263): GuzzleHttp\Promise\Promise->waitIfPending()
#8 ...\vendor\guzzlehttp\promises\src\Promise.php(221): GuzzleHttp\Promise\Promise->invokeWaitList()
#9 ...\vendor\guzzlehttp\promises\src\Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#10 ...\vendor\guzzlehttp\guzzle\src\Client.php(129): GuzzleHttp\Promise\Promise->wait()
#11 ...\vendor\guzzlehttp\guzzle\src\Client.php(87): GuzzleHttp\Client->request('post', 'https://dc.serv...', Array)
#12 ...\vendor\microsoft\application-insights\ApplicationInsights\Channel\Telemetry_Channel.php(178): GuzzleHttp\Client->__call('post', Array)
#13 ...\vendor\microsoft\application-insights\ApplicationInsights\Channel\Telemetry_Channel.php(178): GuzzleHttp\Client->post('https://dc.serv...', Array)
#14 ...\vendor\microsoft\application-insights\ApplicationInsights\Telemetry_Client.php(281): ApplicationInsights\Channel\Telemetry_Channel->send()
#15  Analytics.php(58): ApplicationInsights\Telemetry_Client->flush()

I am using this in a class:

$this->telemetryClient = new \ApplicationInsights\Telemetry_Client();
$this->telemetryClient->getContext()->setInstrumentationKey(INSTRUMENTATION_KEY);
$this->telemetryClient->trackEvent('Test');
$this->telemetryClient->flush();

Note: INSTRUMENTATION_KEY is a constant.

Integrate Application Insights with Drupal8

HI Sir,

First, is it possible integrate Drupal8 with Application Insights? It seems AppInsights which was uploaded to Drupal Module has not been completed.

I make a dir /Drupal_root/compose2 and install application insights with composer.
The next step, I wonder to know how and where to execute $telemetryClient = new \ApplicationInsights\Telemetry_Client();.

Thanks

PHP: trackEvent() not making it to App Insights

Hi All,
I'm attempting to send an event with some custom data to App Insights and I'm not seeing ANY events appearing there. I have confirmed I'm using the correct Instrumentation Key and have used the same block below to send just an event 'name' for testing, with no luck. Any idea what I could be missing? I'm not seeing any errors and I'm not sure how else to troubleshoot this. Any help is much appreciated! My code block:

public static function uploadJobQueueDataAppInsights($intJobQueueId){

$strEventName = "GccJobQueueUpdate";
$objJobQueue = new JobQueue();
$objJobQueue->id = $intJobQueueId;
$objJobQueueDetails = $objJobQueue->getJobQueueById();
$arrJobQueueDetails = (array)$objJobQueueDetails;

if(isset($arrJobQueueDetails[0])){
   $objTelemetryClient = new Telemetry_Client();
   $objContext = $objTelemetryClient->getContext();
   $objContext->setInstrumentationKey(Utilities::APP_INSIGHTS_INSTRUMENTATION_KEY);
   $objTelemetryClient->trackEvent($strEventName, $arrJobQueueDetails[0]);
   $objTelemetryClient->flush();
   unset($objContext, $objTelemetryClient);
}

}

WordPress Plugin/Module

Can this be packaged up as a WordPress Plugin/Module so we can instrument the PHP portion of a WordPress site? We can already add the web page portion via script headers, but that doesn't handle server exceptions, page response time, etc.

MYSQL Queries tracking data not showing in Appinsights dashboard

Hi All,

We have installed Appinsights drupal 7 module with our instrumentation key in module admin level configuration , But our webapp mysql queries data doesn't getting reflected in Appinsights dashboard.

Are we going to sending the mysql query manually for tracking or the tracking will be handled automatically by the help of this module?

We have included Appinsights below javascript code in html.tpl.php front end tracking is working fine by the help of this javascript, my only concern how can we track the backend myqueries data?

"<script type="text/javascript">
var appInsights=window.appInsights||function(config){
function s(config){t[config]=function(){
var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}
var t={config:config},r=document,f=window,e="script",o=r.createElement(e),i,u;
for(o.src=config.url||"//az416426.vo.msecnd.net/scripts/a/ai.0.js",r.getElementsByTagName(e)[0].parentNode.appendChild(o),t.cookie=r.cookie,t.queue=[],i=["Event","Exception","Metric","PageView","Trace"];
i.length;)s("track"+i.pop());return config.disableExceptionTracking||(i="onerror",s("_"+i),u=f[i],f[i]=function(config,r,f,e,o){var s=u&&u(config,r,f,e,o);return s!==!0&&t"_"+i,s}),t }
({ instrumentationKey:"INSKEY"});
window.appInsights=appInsights; appInsights.trackPageView();
</script>"

Thanks in advance

Update the library to reflect the most recent API changes

Since I couldn't find a documentation for the AI API, I figured that the following has to be changed:

  • When passing on the status in trackRequest or endRequest method on ApplicationInsights\Telemetry_Client it is required to be a string not an integer.
  • Similar goes for begingRequest method in ApplicationInsights\Telemetry_Client where the request ID is required to be a string but it is set as integer instead.

The AI API sends a response of HTTP 400 and the message looks like "106: ..."

There is probably more to this, but I haven't discovered it during my usage.

Support Guzzle >=6.2

As per #9 support for the latest Guzzle library would be good.

The current release requires guzzle <= 6.2 - see composer.json L10

This causes conflicts with other libraries.

Not sure if this was just related to the current versions of guzzle available at the time, or if there is really something in 6.2 that will break something here.

Installation issue with guzzlehttp/guzzle version

Hi, I`ve tried to install package with:
composer require microsoft/application-insights
But receive an error:

Problem 1
    - Installation request for microsoft/application-insights ^0.4.5 -> satisfiable by microsoft/application-insights[0.4.5].
    - Conclusion: remove guzzlehttp/guzzle 6.4.1
    - Conclusion: don't install guzzlehttp/guzzle 6.4.1
    - microsoft/application-insights 0.4.5 requires guzzlehttp/guzzle >=5.0 <=6.3.3 -> satisfiable by guzzlehttp/guzzle[5.0.0, 5.0.1, 5.0.2, 5.0.3, 5.1.0, 5.2.0, 5.3.0, 5.3.1, 5.3.2, 5.3.3, 5.3.x-dev, 6.0.0, 6.0.1, 6.0.2, 6.1.0, 6.1.1, 6.2.0, 6.2.1, 6.2.2, 6.2.3, 6.3.0, 6.3.1, 6.3.2, 6.3.3].
    - Can only install one of: guzzlehttp/guzzle[5.3.1, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.3.2, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.3.3, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.3.x-dev, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.0.0, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.0.1, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.0.2, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.1.0, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.1.1, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.2.0, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.2.1, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.2.2, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.2.3, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.3.0, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.3.1, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.3.2, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[6.3.3, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.0.0, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.0.1, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.0.2, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.0.3, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.1.0, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.2.0, 6.4.1].
    - Can only install one of: guzzlehttp/guzzle[5.3.0, 6.4.1].
    - Installation request for guzzlehttp/guzzle (locked at 6.4.1) -> satisfiable by guzzlehttp/guzzle[6.4.1].

I dont have guzzlehttp as direct package so I cant just decrease its version

Invalid instrumentation key ERROR

hello,when i was Initializing the client and setting the instrumentation key ,i got the error like this,
my background is put magento2's log to Azure application insights,magento2 is a framework made by php,so I found this github project.Does anyone konw what i should to fix it out?
I'm new to php, i'm a python and java programmer,so if i made some Low-level mistakes, please tell me ,thank you so much!

[2019-10-23 03:03:42] main.ERROR: Client error: POST https://dc.services.visualstudio.com/v2/track resulted in a 400 Invalid instrumentation key response:
{"itemsReceived":1,"itemsAccepted":0,"errors":[{"index":0,"statusCode":400,"message":"Invalid instrumentation key"}]}

and my php code is like this:

use ApplicationInsights\Telemetry_Client;

$telemetryClient = new \ApplicationInsights\Telemetry_Client();
$context = $telemetryClient->getContext();

// Necessary
$context->setInstrumentationKey('MYInstrumentationKey');

// Optionalmy
//$context->getSessionContext()->setId(session_id());
//$context->getUserContext()->setId('YOUR USER ID');
//$context->getApplicationContext()->setVer('YOUR VERSION');
//$context->getLocationContext()->setIp('YOUR IP');

// Start tracking
$telemetryClient->trackEvent('name of your event');
$telemetryClient->flush();

code Integrated into the magento2 is like this,

namespace Max\HelloWorld\Controller\Index;

use ApplicationInsights\Telemetry_Client;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Logger\Handler\Debug;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Webapi\Exception;
use Monolog\Logger;

class Test extends \Magento\Framework\App\Action\Action
{
protected $_pageFactory;

public function __construct(
    Context $context,
    PageFactory $pageFactory
)
{
    $this->_pageFactory = $pageFactory;
    return parent::__construct($context);
}

public function execute()
{
    echo "Hello World";
    exit;
}

public function postLogger()
{
    echo "Start";
    $telemetryClient = new  Telemetry_Client();
    $context = $telemetryClient->getContext();

    $context->setInstrumentationKey('myInstrumentationKey');

    $telemetryClient->trackEvent("Zhou-loggerInfo", Logger::DEBUG);
    //$telemetryClient->flush();
    echo "End";

}

Bump new version with latest changes

Please, could you bump a new version (0.3.3 I guess) with the latest changes?

We need you to tag a new version in order to be able to install this library through composer if we have the last Guzzle library version (6.2). You have merged the change 4 moths ago but you didn't release a new version yet:
https://github.com/Microsoft/ApplicationInsights-PHP/pull/14/files

Thank you in advance.

Error logs:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - microsoft/application-insights 0.3.0 requires guzzlehttp/guzzle ~5.0 -> satisfiable by guzzlehttp/guzzle[5.0.0, 5.0.1, 5.0.2, 5.0.3, 5.1.0, 5.2.0, 5.3.0, 5.3.1, 5.3.x-dev] but these conflict with your requirements or minimum-stability.
    - Installation request for berriart/apm-bundle ~0.0 -> satisfiable by berriart/apm-bundle[v0.0.1].
    - berriart/apm-bundle v0.0.1 requires microsoft/application-insights ~0.3 -> satisfiable by microsoft/application-insights[0.3.0, 0.3.1, 0.3.2].
    - microsoft/application-insights 0.3.1 requires guzzlehttp/guzzle >=5.0 <=6.1.0 -> satisfiable by guzzlehttp/guzzle[6.1.0].
    - microsoft/application-insights 0.3.2 requires guzzlehttp/guzzle >=5.0 <=6.1.0 -> satisfiable by guzzlehttp/guzzle[6.1.0].
    - Conclusion: don't install guzzlehttp/guzzle 6.1.0

Exception Handling

http://php.net/manual/en/function.set-exception-handler.php

using application Insights on PHP 7 + Wordpress + Application Insights Plugin, the handler throw a Throwable object not an exception, the Registering an exception handler section used on plugin is invalid on php 7, please im not a php developer to make a beautiful change, only override the method trackException to trackThrowable hehehe please make a fix.

Start time doesn't support ms.

This makes is pretty much useless when comparing telemetry events.

The ISO string returned from this utility is only accurate to the second.

$envelope->setTime(Contracts\Utils::returnISOStringForTime($startTime));

And all start times should use microtime();

Actual Behavior

Start times are truncated at seconds.

Expected Behavior

All times should be accurate to at least milliseconds.

Workaround

We've had to implement a workaround right before flushing. We store the start_time in microseconds, then rewrite the start time right before flushing.

How do you get the page loading time?

Right now when I use the trackPageView() function I'm always getting a page load time of 0 (except when using the fixed number of 256 in the second example). It doesn't make sense to use a fixed number, obviously, since I'm trying to get how long it took the page to load.

Instead of 256 in this example:
$telemetryClient->trackPageView('myPageView', 'http://www.foo.com', 256, ['InlineProperty' => 'test_value'], ['duration' => 42.0]);

How do I correctly get the page loading time?

Thanks,
Nathan

PHP Fatal error: 503 Service Unavailable

hello,

I get this error when I want to make the track Event. can anyone help me?

PHP Fatal error: Uncaught exception 'GuzzleHttp\Exception\ServerException' with message 'Server error: POST https://dc.services.visualstudio.com/v2/track resulted in a 500 Processing error response:
{"itemsReceived":1,"itemsAccepted":0,"errors":[{"index":0,"statusCode":500,"message":"Processing error"}]}
' in D:\home\site\wwwroot\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php:113
Stack trace:
#0 D:\home\site\wwwroot\vendor\guzzlehttp\guzzle\src\Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response))
#1 D:\home\site\wwwroot\vendor\guzzlehttp\promises\src\Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp{closure}(Object(GuzzleHttp\Psr7\Response))
#2 D:\home\site\wwwroot\vendor\guzzlehttp\promises\src\Promise.php(156): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), Array)
#3 D:\home\site\wwwroot\vendor\guzzlehttp\promises\src\TaskQueue.php(47): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise{closure}()

in D:\home\site\wwwroot\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php on line 113

thanks

PHP Fatal error: Call to a member function jsonSerialize() on string in D:\home\site\vendor\microsoft\application-insights\ApplicationInsights\Channel\Contracts\Utils.php on line 41

There is a problem with the getUnderlyingData method in \Channel\Contracts\Utils.php.

The method cycles through data items and performs different actions depending on if the item has the method jsonSerialize, if it is an array or another data type.

The relevant code is as follows:

if (method_exists($dataItem, 'jsonSerialize') == true)
{
    $queueToEncode[$key] = Utils::getUnderlyingData($dataItem->jsonSerialize());
}

If a class name (string) is passed as the first parameter to the method_exists function, that class will be checked to see if the method exists. If that class contains a jsonSerialize method (e.g. Illuminate\Database\Eloquent\Model in the Laravel framework), the check passes, which results in the function calling the jsonSerialize method on the class name string, resulting in the "call to a member function on string" error.

I believe the intended behaviour is to call the jsonSerialize method if the $dataItem is an object; therefore I believe the following minor alteration to the code will fix the behaviour:

if (is_object($dataItem) && method_exists($dataItem, 'jsonSerialize') == true)
{
    $queueToEncode[$key] = Utils::getUnderlyingData($dataItem->jsonSerialize());
}

Operation name is empty

When I run trackRequest with trackDependency, all data are submitted in AI database successfully. But there is missing Operation Name, Id in database. The efect of this is that on Azure portal in Performance blade are Operations missing. I was comparing data sent from .Net project and there is Operation reported correctly.
Is there any workaround how to setup Operation ?

Use batching and retries when sending to backend (was: 503 Service Unavailable)

I often get 503 Service Unavailable from Microsoft ApplicationInsight. So, you should send the telemetry data asynchronously. To get around it I am using Laravel's queues.

Also from Microsoft:

"Officially supported SDKs have retry mechanism, and proper back-off logic, which would mitigate the impact on the app and ingestion issues. "

Feature to swallow all errors, or just specific errors

We have hit the daily cap limit, and AI bombs out with:

PHP Fatal error: Uncaught exception 'GuzzleHttp\\Exception\\ClientException' with message 'Client error: POST https://dc.services.visualstudio.com/v2/track` resulted in a 439 Daily quota exceeded response:\n{"itemsReceived":4,"itemsAccepted":0,"errors":[{"index":0,"statusCode":439,"message":"Daily quota exceeded"},{"index":1, (truncated...)\n' in /var/app/current/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:107\nStack trace:\n#0 /var/app/current/vendor/guzzlehttp/guzzle/src/Middleware.php(65): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response))\n#1 /var/app/current/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response))\n#2 /var/app/current/vendor/guzzlehttp/promises/src/Promise.php(156): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), Array)\n#3 /var/app/current/vendor/guzzlehttp/promises/src/TaskQueue.php(61): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\ in /var/app/current/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php on line 107`

It would be nice if we can make AI to ignore either all exceptions, or specific one's.
I don't think it's good if "logging code" throws errors by default.

Custom request headers in web server logs

When a web app is behind Cloudflare, all visitor IPs come Cloudflare's IPs. Cloudflare does forward the original visitor IP with a custom request header. I want to log this value in my web server logs. In IIS this is achieved with Advanced Logging, but this capability does not seem available in Azure web apps. My app is php based wordpress site.

App Ins - PHP webapp

Hi All,

I need some assistance.

Well, I have configured AppIns with an PHP WebApp using Instrumentation Key as shown in this page.
Now, my requirement is to see -

  1. Which page of the website gets the most request/hits in a graph.
  2. Which page of the website gets the less response or takes time to load or refresh.

Any lead or help will be highly appreciated. Thank you in advance.

Not possible to link an exception (or anything) to a request

The backend links requests and other telemetry calls during that request by using the request's id as the context.id in other calls.

but right now, the request id isn't settable because it gets created only when the request is sent. you can properly set the context.id for everything, but not using the value from request.

It appears there should be some concept of BeginRequest on TelemetryClient which you can call at the beginning of a request, get the id from that, use it to set context.id, and then call EndRequest when the request is completed?

Server / Browser exception

Hi

Currently all my exceptions are reported as Browser Exceptions, but obviously PHP errors are Server Exceptions, which means something is either wrong with the AI client, or I'm using it incorrectly.

My code is as simple as:

$this->telemetryClient->trackException($e, ['message' => $formatted]);
$this->telemetryClient->flush();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.