A Console Routine on Channeling NATS. Let’s GO!
Sharing my initial learnings using NATS, Golang Channels & Tview. This article is a short example of NATS - an open source messaging system, TVIEW - Golang based Terminal UI library, concurrency in Golang using Channels and Goroutines. The source code can be found on Github. I have recently started working on a personal Golang project to develop something similar to Uptime Kuma which is a self-hosted monitoring tool. I believe it’s a perfect project with the right complexity to learn advanced concepts of Go. The project code in Github has 4 directories: NATS is a simple, secure and performant communications system and data layer for digital systems, services and devices. It’s used in this example project for pub-sub messaging (shipping) telemetry data from target remote servers to the central server. To keep things simple for this example, we are using an embedded NATS server which is setup in the central server as below: Line #2 denotes that the embedded NATS server should run on port 4222. Line #8 When this line executes, Let’s look at the agent code Line 2 Line 22 TL;DR
What

NATS
The NATS server
1 opts := &natsServer.Options{
2 Port: 4222,
3 }
4 ns, err := natsServer.NewServer(opts)
5 if err != nil {
6 log.Fatal(err)
7 }
8 go ns.Start()
go ns.Start() The go keyword creates a new goroutine, which is a lightweight thread managed by the Go runtime. Goroutines are a fundamental part of Go’s concurrency model.ns.Start() runs concurrently with the rest of the program. The main execution doesn’t wait for this method to complete but continues immediately to the next line. Such pattern is commonly used when launching background services, servers, or long-running processes that need to operate independently of the main program flow.
Publishing NATS message
1 func main() {
2 nc, err := nats.Connect("nats://127.0.0.1:4222")
3 if err != nil {
4 log.Fatal(err)
5 }
6 defer nc.Close()
7 log.Println("Connected to NATS server at", nc.ConnectedUrl())
8 for c := time.Tick(1 * time.Second); ; <-c {
9 v, _ := mem.VirtualMemory()
10 cpuPercent, _ := cpu.Percent(0, false)
11 diskUsage, _ := disk.Usage("/")
12
13 stats := &api.BaseStatsReply{
14 Cpu: &cpuPercent[0],
15 Mem: &v.UsedPercent,
16 Disk: &diskUsage.UsedPercent,
17 }
18 msg, err := proto.Marshal(stats)
19 if err != nil {
20 log.Fatal(err)
21 }
22 err = nc.Publish("host.stats.1", msg)
23 if err != nil {
24 log.Fatal(err)
25 }
26 log.Printf("Published message to NATS server, #%v", stats)
27 }
28 }
nats.Connect("nats://127.0.0.1:4222") initializes client connection to the NATS server.nc.Publish("host.stats.1", msg) publishes a single Protobuf serialized message containing the host base stats viz. CPU utilization, Memory utilization & Disk Usage.Why