Giter Site home page Giter Site logo

sqshq / sampler Goto Github PK

View Code? Open in Web Editor NEW
12.2K 158.0 542.0 2.18 MB

Tool for shell commands execution, visualization and alerting. Configured with a simple YAML file.

Home Page: https://sampler.dev

License: GNU General Public License v3.0

Go 99.71% Dockerfile 0.29%
shell visualization cmd terminal charts alerting sampler command-line command-line-tool monitoring

sampler's Issues

can't run on ubuntu server

I get this on ubuntu server 18.04

panic: oto: ALSA error: No such file or directory

goroutine 1 [running]:
github.com/sqshq/sampler/asset.NewAudioPlayer(0x0)
	/home/sqshq/go/src/github.com/sqshq/sampler/asset/player.go:24 +0x188
main.main()
	/home/sqshq/go/src/github.com/sqshq/sampler/main.go:86 +0xf0

getPlatformStoragePath won't find my $HOME

(You make a commit, 8 hours after that someone complains about it. Internet is wild.)

In metadata/storage.go, the getPlatformStoragePath function is unable to find my $HOME:

2019/08/03 11:45:28 Failed to init storage: mkdir /.config: permission denied

$HOME is properly set and available in the environment variables.

I'm not a Go guy, but this may be related.

Thanks!

[Suggestion] Variables that are shared across elements, but are run every sample time

So while making a stupidly long script for github status retrieving. i realised that i could probably have the speed increased a tonne if each of my elements were able to use the same data.

Specifically, say i have a json downloaded from github's API. and i parse any "usable" statistics from it (say issue count, pr count, stars, forks, watchers, commits, etc). normally i'd have to parse all that data on each element. what would be nice, is something similar to how you can have variables, you share it across multiple elements (same instance and etc), however it has a rate-ms still. other elements then use this variable in the multistep-init, or other things alike.

Would be nice to have.

Currently i could technically cache the data in a temp .json file or etc, but where's the fun in that?

Cannot use MySQL query as a source for runcharts

Hi!

I'm trying to setup monitoring of number of records per minute in a table. It works like a charm when when using sparklines, but show nothing if I switch to runcharts.
Am I doing something wrong or MySQL is not supported for runcharts yet? Thank you!

variables:
  mysql_connection: mysql -u user -s --database someDBName  --skip-column-names
runcharts:
  - title: App log messages
    position: [[40, 0], [40, 24]]
    rate-ms: 1000
    legend:
        enabled: true
        details: true
    scale: 2
    items:
      - label: Errors
        init: $mysql_connection
        sample: SELECT RAND();
      - label: Warnings
        init: $mysql_connection
        sample: SELECT RAND();
sparklines:
  - title: MySQL (random number example)
    pty: true
    init: $mysql_connection
    sample: SELECT RAND();

Windows version require SH

Windows version require sh but default command interpreter in Windows OS is cmd.exe

SAMPLING FAILURE exec: "sh": executable file not found in %PATH%

Исполняемый файл под Windows, пытается запустить внешние программы через SH. Командным интерпретатором в операционных системах Windows является cmd.exe.

Feature Request - Runchart legend position

Before the actual request, just want to say that like others, I've only known about this tool for a few days and I already love it. Thank you so much for building it!

For run charts, is it possible to add an option for which corner to anchor the legend to? Since the most recent data is on the right, the legend sometimes covers up some of that data.

ANSI-formated text in logs

Hi!
My logs are colour formatted using ANSI escape codes. But when I trying to "tail" them into textbox, I have got unformatted text, like: [31merror[39m, instead if red "error". Would you add ANSI support?

Feature Request - Reuse init command for multiple charts

The example configuration suggests using an init command for things that require some initial setup, such as getting performance metrics from a database server. In some cases, multiple charts may be fetching data from the same source, so it would be convenient if the sample instance of an init command could be reused somehow. This would be useful for e.g. setting up charts for multiple production servers, separately showing CPU load and RAM usage, where both data sets are coming from the same data source.

Unicode characters not rendering properly in WSL

Hi there, nice product btw

When I execute sampler with a sample config.yml file, the charts display a '?' inside a square where should be a point or a line to display the chart properly.

I guess this should be because my computer doesn't have the font, or the correct character to display.

Enviroment:
Ubuntu 18.04.2 LTS
Executing Ubuntu from windows throught WSL (not virtual machine!)

I'm in love

Honestly, I have no real use for this, but I had to tell you how much I love it. I'm trying to find a use case, I love it so much.

Maybe if you made some way of working with Prometheus trivial?

But anyway, thanks for brightening my day!

FreeBSD support (Linux® Binary Compatibility)

Hello,
I have currently tested sampler on FreeBSD with Linux layer, I can not get past "License info", it seems that keyboard events are not working.
I have compiled sampler without that intro and I can see that sampler is indeed working on FreeBSD but like I said there is some issue with keyboard events handling.

There is a chance I will look more into it but let's for now just create an issue

[Question] Triggers in textboxes

Hey guys, is it possible to use Triggers in Textboxes?
I'm trying to make a "ping machine" to determine whether the webserver is online. If not - make an alarm.

textboxes:
  - title: Google
    sample: curl -o /dev/null -s -w '%{http_code}'  https://google.com
    triggers:
      - title: Server down
        condition: echo "$cur != 200" | bc -l
        actions:
            visual: true
            script: 'say alert: ${label} server is Down'

Right now the config shows me an error: TRIGGER CONDITION FAILURE fork/exec /bin/sh: invalid argument

I can't figure out how can I overcome this. Please help :)

Default config

Would it be possible to add either a default config location (Maybe user .config directory?) or a way to set a default location to always look for a config from?
Would mean you can just run the binary, rather than having to include the config flag. Just saves a little bit of time 😄

Feature request - Multiple display "pages"

Would it be possible to add some form of pages that can be switched between? Similar to how a security camera system has multiple cameras/ camera groupings that it flips through.

If you would have it if i made it, I would love to work on this myself.

Explicit min/max for sparklines and runcharts?

Can we explicitly set the min/max on the scale for sparklines and/or runcharts? I've tried and it doesn't seem to respond. I should probably just use gauges, but I like seeing the history. I'd just like to define the vertical axis' min/max.

Where is your color palette defined?

I'm trying to run your runcharts.yml example, but I'm not a fan of the color you chose for Google. It seems to me that it is closer to the color that should be used for Yahoo.

So, this has sent me down the rathole of trying to figure out where your color palette is defined, so that I can find the appropriate Web-safe or HTML color that would most appropriately represent different entities, and then map that back to the closest matching 8-bit color.

But I can't find anything anywhere in your repo that makes this mapping obvious.

Can you help me out here? Is there a standard Go reference that I'm not aware of? Thanks!

Create some pre-built configs

Currently there is a single example config file which serves as a great starting point, but it would be nice to have a few pre-built configs for people to drop in and go.

Some examples:

  • One designed entirely around Docker and monitoring container metrics.
  • Another designed to look pretty and having an overview of system metrics.

Cannot run sampler on MacOS Catalina [10.15 Beta (19A558d)]

When I try to run sampler from shell (both ZSH and BASH) I get an error popup saying that "Application sampler-1.0.3-darwin-amd64 cannot be opened, because its identity cannot be verified".

I suspect that it has to do something with Catalinas security improvements/enforcement.

The first two lines of "top" output is not visible in textboxes

I don't see the top two lines (with uptime, load averages, taks, etc) of the "top" command output in textboxes.

This is the output of the command:

top - 16:17:43 up 1 day,  9:59,  1 user,  load average: 3.86, 5.15, 5.02
Tasks: 1955 total,   4 running, 1923 sleeping,   0 stopped,  28 zombie
%Cpu(s):  7.1 us,  2.2 sy,  0.0 ni, 89.6 id,  0.5 wa,  0.0 hi,  0.5 si,  0.0 st
KiB Mem : 73932664 total, 20585044 free, 42106204 used, 11241416 buff/cache
KiB Swap: 16777212 total, 16777212 free,        0 used. 29785392 avail Mem

This is what I see in a textbox:

┌─ SSH AP12-CTRL3 ─────────────────────────────────────────────────────────────────┐
│                                                                                  │
│ %Cpu(s): 25.8 us,  4.5 sy,  0.0 ni, 67.1 id,  1.6 wa,  0.0 hi,  1.1 si,  0.0 st  │
│ KiB Mem : 73932664 total, 19868300 free, 42800772 used, 11263592 buff/cache      │
│ KiB Swap: 16777212 total, 16777212 free,        0 used. 29081084 avail Mem       │
│     PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND    │
│   40153 42435     20   0  505252 262224   2312 R  87.5  0.4 184:04.73 neutron-+  │
│   39890 42434     20   0   17.1g   1.8g 145996 S  78.5  2.6 642:54.60 mysqld     │
│   40149 42435     20   0  504192 261164   2312 S  75.0  0.4 184:18.85 neutron-+  │
│   36016 42439     20   0   19.5g   1.1g   4468 S  71.5  1.5 941:18.90 beam.smp   │
│   40146 42435     20   0  534168 284064   2312 S  62.5  0.4 174:22.72 neutron-+  │
│  398434 openvsw+  10 -10 2310908 107236  13752 S  39.0  0.1 198:12.35 ovs-vswi+  │
└──────────────────────────────────────────────────────────────────────────────────┘

I tried moving and resizing of the textbox, doesn't help. Textbox config is very simple:

  - title: SSH AP12-CTRL3
    position: [[0, 25], [50, 13]]
    rate-ms: 2000
    pty: true
    init: $ctrl3
    sample: top

I can see the two missing line if I change sample: top to sample: echo; top. But, these lines would be printed as second and third and the first line would contain data from the last:

┌─ SSH AP12-CTRL3 ─────────────────────────────────────────────────────────────────┐
│                                                                                  │
│ 24856 42435     20   0  652288 321340   8144 S   8.5  0.4 146:25.65 neutron-+    │
│ top - 16:24:08 up 1 day, 10:05,  2 users,  load average: 5.34, 5.88, 5.51        │
│ Tasks: 2025 total,   6 running, 1989 sleeping,   0 stopped,  30 zombie           │
│ %Cpu(s): 13.9 us,  3.0 sy,  0.0 ni, 81.7 id,  0.7 wa,  0.0 hi,  0.7 si,  0.0 st  │
│ KiB Mem : 73932664 total, 20154456 free, 42510780 used, 11267428 buff/cache      │
│ KiB Swap: 16777212 total, 16777212 free,        0 used. 29378672 avail Mem       │
│     PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND    │
│   40148 42435     20   0  523576 274008   2312 R  92.5  0.4 179:48.86 neutron-+  │
│   36016 42439     20   0   19.5g   1.1g   4468 S  57.0  1.5 943:32.69 beam.smp   │
│   40151 42435     20   0  514352 271324   2312 R  56.0  0.4 179:21.51 neutron-+  │
└──────────────────────────────────────────────────────────────────────────────────┘

Segfault when asciibox contains a newline

If you try this config, it works:

asciiboxes:
  - title: ""
    sample: date +%r%D

Now try adding a newline in the date format (%n):

asciiboxes:
  - title: ""
    sample: date +%r%n%D

And I get:

panic: runtime error: index out of range

goroutine 36 [running]:
github.com/mbndr/figlet4go.(*font).getCharSlice(0xc00018e420, 0xc00000000a, 0xc0002ce4e0, 0x6, 0x6)
	/home/sqshq/go/src/github.com/mbndr/figlet4go/font.go:46 +0x1b9
github.com/mbndr/figlet4go.newAsciiChar(0xc00018e420, 0xc00000000a, 0xc0000122a0, 0x0, 0x0)
	/home/sqshq/go/src/github.com/mbndr/figlet4go/char.go:24 +0xa3
github.com/mbndr/figlet4go.(*AsciiRender).RenderOpts(0xc0001c8010, 0xc0000d2000, 0x14, 0xc0001ce070, 0x14, 0x0, 0x0, 0x0)
	/home/sqshq/go/src/github.com/mbndr/figlet4go/render.go:72 +0x108
github.com/sqshq/sampler/component/asciibox.NewAsciiBox.func1(0xc000252000)
	/home/sqshq/go/src/github.com/sqshq/sampler/component/asciibox/asciibox.go:62 +0x18a
created by github.com/sqshq/sampler/component/asciibox.NewAsciiBox
	/home/sqshq/go/src/github.com/sqshq/sampler/component/asciibox/asciibox.go:57 +0x5ff

Running on Linux ARM?

Hi folks! This looks great. I want to try it out on an ARM box of mine, but the executable doesn't work, of course. I'll grab the source and see if I can make it go, but any thoughts on adding an "advanced linux installation" section or something?

Linux/Ubuntu useful configurations/pipes thread

Hi,

This topic is dedicated to sharing useful pipes that enhances the sampler experience on GNU/Linux/Ubuntu. Don't hesistate to share! Here are mines:

HTOP
Requires: aha, html2text

textboxes:
  - title: HTOP
    rate-ms: 1000
    color: 122
    sample: echo q | htop -C | aha --line-fix | html2text -width 999 | grep -v "F1Help\|xml version="

HTOP OVER SSH
Requires: aha, html2text
Warning: Significant CPU load on devices such as raspberry pi.

textboxes:
  - title: HTOP
    rate-ms: 1000
    color: 121
    pty: true
    init: ssh -i ~/.ssh/id_rsa user@host
    sample: echo q | htop -C | aha --line-fix | html2text -width 999 | grep -v "F1Help\|xml version="

POSTGRESQL single line query

barcharts:
  - title: Database Distribution
    rate-ms: 180000
    scale: 0
    items:
      - label: Record Count
        sample: PGPASSWORD=PASSWORD psql -h host -U user --no-align --tuples-only -c 'select count(*) from tablename'

Periodic directory count
Requires: dircnt

barcharts:
  - title: Directory Counts
    rate-ms: 180000
    scale: 0
    items:
      - label: Master
        sample: /path/to/dircnt /path/to/target/directory/ | awk {'print $3'}

Linux invalid memory addres or nil pointer deference on strart

Have crash at start after nothing changed (working config, open in vim, close vim, restart, not working config)
ArchLinux, linux 5.2.0, sampler v 1.0.2
Error:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x555ea1784b2d]

goroutine 8 [running]:
main.verifyLicense(0xc000013c20, 0xc000013aa0)
	main.go:146 +0x2d
created by main.main
	main.go:107 +0x983

Config:

variables:
  sshconnection: ssh -C -i ~/.ssh/rsa_weak user@ip
runcharts:
  - title: Search engine response time
    init: $sshconnection
    pty: true
    position: [[0, 7], [40, 24]]
    rate-ms: 500
    legend:
        enabled: true
        details: false
    scale: 2
    items:
      - label: GOOGLE
        color: 178
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com
      - label: BING
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.bing.com
sparklines:
  - title: CPU usage
    position: [[40, 7], [40, 24]]
    rate-ms: 200
    scale: 0
    sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
  - title: Free memory pages
    position: [[0, 0], [80, 8]]
    rate-ms: 200
    scale: 0
    sample: free | rg 'Mem' | awk '{print $3}'

Fix:

rm -r ~/.config/Sampler

Web page mirroring

Probably not related to this project directly.
But I would love to have this dashboard both in the terminal with ssh access and as a web page.
Is there any simple way to generate dynamic html page based on terminal output?

Some problems about using software in centos 7

1、barcharts:
items:
- label: UDP bytes in
sample: nettop -J bytes_in -l 1 -m udp | awk '{sum += $4} END {print sum}'
Nettop is a command in mac. Can CentOS now use commands similar to this function to help? Thanks
2、asciiboxes
About the asciiboxes option。Whether I use it on the Mac or in centos, it doesn't show up. I'm wondering if there are additional steps that I haven't done, such as the requirement for date format. Seek your help。thanks
1565322972675
1565323006200

Free memory pages on Ubuntu

on ubuntu memory_pressure need change to free:

sample: memory_pressure | grep 'Pages free' | awk '{print $3}'

to

    sample: free -w | grep 'Mem' | awk '{print $3}'

but how the nettop command be solved on ubuntu ?

Running sampler on catalina prompts alert...

------------- alert ------------------
“sampler-1.0.2-darwin-amd64” can’t be opened because its integrity cannot be verified.

This software needs to be updated. Contact the developer for more information.

Move to Trash | Cancel
------------- end alert --------------

encoding problems

I am using WSL (https://docs.microsoft.com/en-us/windows/wsl/install-win10) Debian GNU/Linux and I'm having problems with the encoding
/etc/default/locale:

#  File generated by update-locale
LC_ALL=C
LANGUAGE=en_US.UTF-8

/etc/default/keyboard:


# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT="rus"
XKBOPTIONS=""

BACKSPACE="guess"

image

libasound is mandatory for startup on Linux

when trying to run on latest WSL with Ubuntu, getting the following error:
sampler: error while loading shared libraries: libasound.so.2: cannot open shared object file: No such file or directory

rate-ms appears to be not honoured in gauges

I've set rate-ms to 10000 but it is updated at least once a second. The full block is:

gauges:
  - title: Memory used (MiB)
    position: [[0, 20], [20, 4]]
    rate-ms: 10000
    scale: 0
    color: 58
    cur:
      sample: env LC_ALL=C free -m | grep ^Mem | awk '{print $3}'
    max:
      sample: env LC_ALL=C free -m | grep ^Mem | awk '{print $2}'
    min:
      sample: echo 0
    triggers:
      - title: Low memory
        condition: '[ $label == "cur" ] && [ $cur -ge 15000 ] && echo 1 || echo 0'
        actions:
            visual: true

Scp in init returns a "write broken pipe" error

Hi, I try to copy a local script to my remote server in the init then execute it.

    - title: status
      #rate-ms: 60000
      multistep-init:
        - scp monit.sh raspberry:/tmp/monit.sh
        - ssh raspberry
      sample: sh /tmp/monit.sh

But the scp command seems to fail with the following error:

    SAMPLING FAILURE failed to execute command: write |1: broken pipe

All commands work properly outsite of sampler.
The monit.sh script is in the current working directory.
I also try to use absolute path with no success.

Tested on Ubuntu mate with amd-64 binary and the remote server is a raspberry pi.

Add templating

Hi,

It could be great to have go template to loop over stuff in the yaml config file.

Run actions on a textboxes item

Sometimes it might be useful to run a user-defined action for an item being monitored, e.g. kill/restart/reload etc. It looks like currently it only makes sense for textboxes items.

It would be nice if I can select an item and press enter to run a pre-configured action. Going further, there can be a pop-up menu with several items.

Support for Raspberry PI

I'm trying to set up sampler to work as a dashboard running on a Raspberry PI.
I managed to get it to compile on the PI but when i try to run it i get the following error:

# sampler --config conf.yml
panic: non-positive interval for NewTicker [recovered]
        panic: non-positive interval for NewTicker

goroutine 1 [running]:
main.handleCrash(0x108e5a0, 0x10708a0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1075cc0)
        /root/sampler-1.0.3/main.go:127 +0x170
panic(0x339418, 0x100e198)
        /usr/lib/go-1.11/src/runtime/panic.go:513 +0x194
time.NewTicker(0xd964b800, 0xffffffff, 0x123a5a0)
        /usr/lib/go-1.11/src/time/tick.go:23 +0x1bc
github.com/sqshq/sampler/data.NewSampler(0x1085310, 0x1085320, 0x3, 0x4, 0x650634, 0x0, 0x0, 0x10708a0, 0x0, 0x0, ...)
        /root/sampler-1.0.3/data/sampler.go:20 +0x2c
main.(*Starter).start(0x10d7f30, 0x3eb490, 0x1183b80, 0x1085310, 0x107ad70, 0xb, 0x10759c0, 0x2, 0x2, 0x107bd88, ...)
        /root/sampler-1.0.3/main.go:68 +0x288
main.(*Starter).startAll(0x10d7f30, 0x1202000, 0x1196060, 0x1196090)
        /root/sampler-1.0.3/main.go:49 +0x538
main.main()
        /root/sampler-1.0.3/main.go:115 +0x26c

Allow nested components

It'd be nice to have something like:

--- My dashboard ----------------
| Component:1     | Component:2 |
|                               |
| Component:3                   |
---------------------------------

throws SIGSEV on WSL

Using sampler on Windows subsystem for linux throws SIGSEV.

Below is the config file used.

╭─nd33p@trv-wl-srenjith ~
╰─$ cat test.conf
variables:
  sshconnection: ssh [email protected]
textboxes:
  - title: SSH
    pty: true
    init: $sshconnection
    sample: top

Below are the errors thrown

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x463252] goroutine 45 [running]: io.WriteString(0x0, 0x0, 0xc0005b6018, 0x5, 0x0, 0xc0005b6018, 0x5) /usr/lib/go-1.12/src/io/io.go:293 +0xc2 github.com/sqshq/sampler/data.(*PtyInteractiveShell).execute(0xc0002ea000, 0x0, 0x0, 0x0, 0x0) /home/sqshq/go/src/github.com/sqshq/sampler/data/int_pty.go:70 +0x128 github.com/sqshq/sampler/data.(*Item).nextValue(0xc0000fe180, 0xc0001c0020, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0) /home/sqshq/go/src/github.com/sqshq/sampler/data/item.go:57 +0x60 github.com/sqshq/sampler/data.(*Sampler).sample(0xc0001a6120, 0xc0000fe180, 0xc0000906c0, 0x0, 0x0, 0x0, 0x0) /home/sqshq/go/src/github.com/sqshq/sampler/data/sampler.go:59 +0x58 created by github.com/sqshq/sampler/data.NewSampler.func1 /home/sqshq/go/src/github.com/sqshq/sampler/data/sampler.go:35 +0x86

Compilation error for ARM architecture

src/github.com/sqshq/sampler$ GOOS=linux GOARCH=arm go build
# github.com/hajimehoshi/oto
../../hajimehoshi/oto/context.go:69:12: undefined: newDriver

Failed to parse a number: strconv.ParseFloat on Runcharts

Set up exactly like in the tutorial. Running on ubuntu.

runcharts:
  - title: Search engine response time
    rate-ms: 500        # sampling rate, default = 1000
    scale: 2            # number of digits after sample decimal point, default = 1
    legend:
      enabled: true     # enables item labels, default = true
      details: false    # enables item statistics: cur/min/max/dlt values, default = true
    items:
      - label: GOOGLE
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
        color: 178      # 8-bit color number, default one is chosen from a pre-defined palette
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com
      - label: BING
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.bing.com

error

Sample output from 'curl -o /dev/null -s -w '%{time_total}' https://www.bing.com' : 0,435571

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.