# How to graph my clients?

**URL:** https://forum.syncthing.net/t/how-to-graph-my-clients/19554
**Category:** Support
**Created:** [December 29, 2022, 7:06pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554 "2022-12-29T19:06:30Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [December 29, 2022, 7:06pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/1 "2022-12-29T19:06:30Z")

</div>

I have a few clients that send, receive or sync data. The relationships are sometimes complicated and I would love to see them as a graph between clients, data, and kind of connection (send, receive, sync).

Is there a way to do that one way or another? (short of drawing them myself)

---

<div class="post-metadata">

### Author: ![martinleben](https://forum.syncthing.net/user_avatar/forum.syncthing.net/martinleben/32/9049_2.png) [@martinleben](https://forum.syncthing.net/u/martinleben)
#### Post date: [December 29, 2022, 8:24pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/2 "2022-12-29T20:24:02Z")

</div>

No. A Syncthing device only has knowledge about its peers, not the entire network.

---

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [December 29, 2022, 8:53pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/3 "2022-12-29T20:53:21Z")

</div>

Yes, I understand this but I was hoping that by analyzing the configuration of all my clients there wild be a way to lmao them that way.

---

<div class="post-metadata">

### Author: ![acolomb](https://forum.syncthing.net/user_avatar/forum.syncthing.net/acolomb/32/11343_2.png) [@acolomb](https://forum.syncthing.net/u/acolomb)
#### Post date: [January 5, 2023, 1:15am UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/4 "2023-01-05T01:15:13Z")

</div>

Actually every node knows its own connected devices and shared folders, plus every other device directly sharing the same folder with one of the connected remote devices. In other words, the local perspective tells you every involved device that is one or two hops away. In a straight linear topology A - B - C - D, that means A can know about B (directly) and C (indirectly), but not D.

This info is all contained in the ClusterConfig messages exchanged each time a connection is established. However, Syncthing currently does not expose it in any way for analysis or plotting. Something I’d like to implement in the long term.

If you do find or develop a solution how to visualize device and folder relationships (even if generated from a manual description of the links), I’d be very interested so please do share it here in case.

---

<div class="post-metadata">

### Author: ![tomasz86](https://forum.syncthing.net/letter_avatar_proxy/v4/letter/t/96bed5/32.png) [@tomasz86](https://forum.syncthing.net/u/tomasz86)
#### Post date: [January 5, 2023, 7:36am UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/5 "2023-01-05T07:36:15Z")

</div>

> [@acolomb](#):
>
> If you do find or develop a solution how to visualize device and folder relationships (even if generated from a manual description of the links), I’d be very interested so please do share it here in case.

I would love to be able to use something like this too!

For now, I’ve always resorted to simply drawing the whole thing by hand, but the obvious disadvantage is that you need to re-do everything each time there are changes to the configuration. This could, however, be mitigated by drawing on a computer with a stylus (which I’ve actually got but I’m not a digital artist and drawing by hand still feels more natural to me 😅).

---

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [January 5, 2023, 7:44am UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/6 "2023-01-05T07:44:43Z")

</div>

@acolomb @tomasz86 I started to develop a very rudimentary tool that takes all the `config.xml` files that are available to someone (in my case several of them, plus a few on the family devices that I may or may not have access to).

My idea is to plot the basic relationships (who sends what where, and the type (synch, receive / send only)) via `mermaid.js`. Or something different if there is a better way.

I would love to automatically get the data via the API but this is very limitative and wild work only when all devices are within one network (which in my case could be possible, especially if I continuously try to pull the data).

The obvious drawback is that with the vibe files the plot is a one-shot.

---

<div class="post-metadata">

### Author: ![tomasz86](https://forum.syncthing.net/letter_avatar_proxy/v4/letter/t/96bed5/32.png) [@tomasz86](https://forum.syncthing.net/u/tomasz86)
#### Post date: [January 5, 2023, 9:44am UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/7 "2023-01-05T09:44:56Z")

</div>

That’s great to hear! I’ll definitely be looking forward to testing it 🙂.

The `config.xml` approach is probably much more flexible. In my network there are devices located in a different country, so just querying the API is a no-go here.

---

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [January 5, 2023, 12:49pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/8 "2023-01-05T12:49:56Z")

</div>

> [@tomasz86](#):
>
> That’s great to hear! I’ll definitely be looking forward to testing it 🙂.

This is not going to happen overnight as I am quite loaded with work, family and the need to finish my smart lock 🙂

But I will add this to my parallelized development because it would really help me to ensure that the configuration is consistent and actually does what I think it does. I gave some thoughts this morning under the shower and I should bootstrap something “soon”, at least a very rough first draft.

---

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [January 5, 2023, 12:51pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/9 "2023-01-05T12:51:32Z")

</div>

> [@tomasz86](#):
>
> In my network there are devices located in a different country, so just querying the API is a no-go here.

Yes, being in another network is a showstopper.

I was considering sharing the configuration (as part of a synching folder share), send only, to a centralized machine but it will be a bit messy. I will see.

---

<div class="post-metadata">

### Author: ![atrent](https://forum.syncthing.net/user_avatar/forum.syncthing.net/atrent/32/13582_2.png) [@atrent](https://forum.syncthing.net/u/atrent)
#### Post date: [January 6, 2023, 11:34am UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/10 "2023-01-06T11:34:01Z")

</div>

something like:

```go
package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
)

type Config struct {
	XMLName xml.Name `xml:"configuration"`
	Folders []Folder `xml:"folder"`
	Devices []Device `xml:"device"`
}

type Folder struct {
	XMLName xml.Name `xml:"folder"`
	Id string `xml:"id,attr"`
	Label string `xml:"label,attr"`
	Path string `xml:"path,attr"`
	Devices []Device `xml:"device"`
}

type Device struct {
	XMLName xml.Name `xml:"device"`
	Id string `xml:"id,attr"`
	Name string `xml:"name,attr"`
}

func main() {
	xmlFile, err := os.Open("config.xml")
	if err != nil {
		fmt.Println(err)
	}
	//fmt.Println("Successfully Opened xml")
	defer xmlFile.Close()

	byteValue, _ := ioutil.ReadAll(xmlFile)

	var conf Config // root
	xml.Unmarshal(byteValue, &conf)

	//fmt.Println("DEBUG", conf)

	/*
		for i := 0; i < len(conf.Folders); i++ {
			fmt.Println(conf.Folders[i])
		}
	*/

	fmt.Println("digraph map {\ngraph [root=\"Distance_0\",ratio=\"1\",rankdir = \"LR\"]")
	// prima estraggo i device coi nomi
	for _, d := range conf.Devices {
		fmt.Printf("\"%s\" [label=\"%s\"]\n", d.Id, d.Name)
	}

	// poi i folders coi link
	for _, f := range conf.Folders {
		fmt.Printf("\"%s\" [label=\"%s\"]\n", f.Id, f.Label)
		//fmt.Printf("\"%s\"\n", f.Id)
		for _, d := range f.Devices {
			fmt.Printf("\"%s\" -> \"%s\"\n", f.Id, d.Id)
		}
	}
	fmt.Println("}")
}

```

---

<div class="post-metadata">

### Author: ![atrent](https://forum.syncthing.net/user_avatar/forum.syncthing.net/atrent/32/13582_2.png) [@atrent](https://forum.syncthing.net/u/atrent)
#### Post date: [January 6, 2023, 12:30pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/11 "2023-01-06T12:30:47Z")

</div>

it generates a .dot file such as:

 ![test](https://forum-uploads.syncthingcdn.net/original/2X/b/b2f197a53bc109a674af168fdb567cd1a4251956.png)

of course you can customize the program to generate different shapes for ‘devices’ and ‘folders’

---

<div class="post-metadata">

### Author: ![atrent](https://forum.syncthing.net/user_avatar/forum.syncthing.net/atrent/32/13582_2.png) [@atrent](https://forum.syncthing.net/u/atrent)
#### Post date: [January 6, 2023, 1:05pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/12 "2023-01-06T13:05:28Z")

</div>

with shapes:

```go
package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
)

type Config struct {
	XMLName xml.Name `xml:"configuration"`
	Folders []Folder `xml:"folder"`
	Devices []Device `xml:"device"`
}

type Folder struct {
	XMLName xml.Name `xml:"folder"`
	Id string `xml:"id,attr"`
	Label string `xml:"label,attr"`
	Path string `xml:"path,attr"`
	Type string `xml:"type,attr"`
	Devices []Device `xml:"device"`
}

type Device struct {
	XMLName xml.Name `xml:"device"`
	Id string `xml:"id,attr"`
	Name string `xml:"name,attr"`
}

func main() {
	xmlFile, err := os.Open("config.xml")
	if err != nil {
		fmt.Println(err)
	}
	defer xmlFile.Close()

	byteValue, _ := ioutil.ReadAll(xmlFile)

	var conf Config // root
	xml.Unmarshal(byteValue, &conf)

	fmt.Println("DEBUG", conf)

	fmt.Println("digraph map {\ngraph [ratio=\"1\",rankdir = \"LR\"]")
	// prima estraggo i device coi nomi
	for _, d := range conf.Devices {
		fmt.Printf("\"%s\" [label=\"%s\",shape=box3d]\n", d.Id, d.Name)
	}

	// poi i folders coi link
	for _, f := range conf.Folders {
		fmt.Printf("\"%s\" [label=\"%s\",shape=folder]\n", f.Id, f.Label)
		//fmt.Printf("\"%s\"\n", f.Id)
		ty := "" // sendonly
		if f.Type == "sendreceive" {
			ty = "[dir=none]"
		}
		if f.Type == "receiveonly" {
			ty = "[dir=back]"
		}
		fmt.Println("DEBUG", f.Type, ty)

		for _, d := range f.Devices {
			fmt.Printf("\"%s\" -> \"%s\" %s\n", f.Id, d.Id, ty)
		}
	}
	fmt.Println("}")
}

```

---

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [January 6, 2023, 1:31pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/13 "2023-01-06T13:31:34Z")

</div>

You are faster than me 🙂

Thanks - this is basically what I want to do, with the addition of

- parsing a config file and its cert generates a JSON object that is indexed with the hostname. Several different configs (and certs) will generate several entries in the JSON which will allow to map several devices
- I will add the direction (type) for each connection, as seen from both sides to check for consistency (when I have one folder as “receiveonly”, I usually have it as “sendonly” on the other side - but not always)
- I will “pack” folders under a host to check for discrepancies in naming

---

<div class="post-metadata">

### Author: ![atrent](https://forum.syncthing.net/user_avatar/forum.syncthing.net/atrent/32/13582_2.png) [@atrent](https://forum.syncthing.net/u/atrent)
#### Post date: [January 6, 2023, 2:44pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/14 "2023-01-06T14:44:27Z")

</div>

- my second example uses “type” to decide the arrow style
- in `dot` you can group nodes (see [DOT Language | Graphviz](https://graphviz.org/doc/info/lang.html))

---

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [January 8, 2023, 7:37pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/15 "2023-01-08T19:37:00Z")

</div>

A very first version is here [https://github.com/wsw70/syncthing-map](https://github.com/wsw70/syncthing-map)

I will be back 🙂

---

<div class="post-metadata">

### Author: ![tomasz86](https://forum.syncthing.net/letter_avatar_proxy/v4/letter/t/96bed5/32.png) [@tomasz86](https://forum.syncthing.net/u/tomasz86)
#### Post date: [January 8, 2023, 7:38pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/16 "2023-01-08T19:38:12Z")

</div>

Unfortunately, the URL seems to be broken 😅. Is this a private repository by any chance?

---

<div class="post-metadata">

### Author: ![Wpq](https://forum.syncthing.net/user_avatar/forum.syncthing.net/wpq/32/12470_2.png) [@Wpq](https://forum.syncthing.net/u/Wpq)
#### Post date: [January 8, 2023, 7:41pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/17 "2023-01-08T19:41:22Z")

</div>

Sorry, I just realized that I kept it as Private. Should be fixed now.

---

<div class="post-metadata">

### Author: ![acolomb](https://forum.syncthing.net/user_avatar/forum.syncthing.net/acolomb/32/11343_2.png) [@acolomb](https://forum.syncthing.net/u/acolomb)
#### Post date: [January 8, 2023, 10:45pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/18 "2023-01-08T22:45:54Z")

</div>

Great, thanks for sharing this! I hope it will keep getting developed and extended upon. If you like, we can add a pointer to the tool in the documentation.

I hope I’ll have time to try it out soon, already had some ideas what could be added, such as differing device names or being able to show when a folder is shared only one way, but not accepted on the other end.

---

<div class="post-metadata">

### Author: ![atrent](https://forum.syncthing.net/user_avatar/forum.syncthing.net/atrent/32/13582_2.png) [@atrent](https://forum.syncthing.net/u/atrent)
#### Post date: [January 9, 2023, 12:29pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/19 "2023-01-09T12:29:30Z")

</div>

And here is my proposal for a graphing tool:

> **[Andrea Trentini / syncthing-graph · GitLab](https://gitlab.com/andrea-trentini/syncthing-graph)**
>
> GitLab.com

It is a simpler ‘one-shot’ tool, give it a bunch of xml files and it spits the .dot

---

<div class="post-metadata">

### Author: ![tomasz86](https://forum.syncthing.net/letter_avatar_proxy/v4/letter/t/96bed5/32.png) [@tomasz86](https://forum.syncthing.net/u/tomasz86)
#### Post date: [January 9, 2023, 12:55pm UTC](https://forum.syncthing.net/t/how-to-graph-my-clients/19554/20 "2023-01-09T12:55:50Z")

</div>

I’ve tried to use it under Windows, but unfortunately it doesn’t seem to be able to open the XML files. For the record, there are two of them in the folder.

```nohighlight
.\syncthing-graph.exe *.xml > graph.dot
*** DEBUG prima del marshal {{ } [] []}
=== Processing file *.xml ( 1 of 1 )
open *.xml: The filename, directory name, or volume label syntax is incorrect.
*** DEBUG dopo marshal {{ } [] []}

```

The problem seems to be about the wildcard, because `.\syncthing-graph.exe config1.xml config2.xml > graph.dot` does work.

[Next page](https://forum.syncthing.net/t/how-to-graph-my-clients/19554.md?page=2)
