ServiceCheck

Service Check is a 64-bit Linux command line tool to check background services/applications and run it if it is not working

it stores configuration for applications to be checked in checklist.ini file in the same directory of servicecheck tool.

example of configuration for application called goagent located in /home/user/go/

checklist.ini contents:

goagent /home/user/go/goagent

WebSocket using Golang

Inspired by the previous Article of Implementing WebSocket with NodeJS, I have tried successfully WebSocket in Go language.

Steps:

First install WebSocket package for Go:

go get github.com/gorilla/websocket

Start new project in Go, and write this HTML content in websockets.html file in project directory:

<!-- websockets.html -->
<h2>WebSocket using Golang</h2>
<h3>Server time</h3>
<pre id="output"></pre>
<script>

    var input = document.getElementById("input");
    var output = document.getElementById("output");
output.innerHTML = location.host;
    var socket = new WebSocket("ws://" + location.host + "/time");

    socket.onopen = function () {
        output.innerHTML = "Status: Connected";
    };

    socket.onmessage = function (e) {
        output.innerHTML = "From Server: <b>" + e.data + "</b>";
    };


</script>

</script>

Then write Go source code as main.go in the same directory of .HTML file :

// GorillaWebSocket project main.go
package main

import (
    "fmt"
    "net/http"
    "strconv"
    "time"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    ReadBufferSize: 1024,
    WriteBufferSize: 1024,
}

var id = 0

func main() {
    http.HandleFunc("/time", timer)

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "websockets.html")
    })

    http.ListenAndServe(":1234", nil)
}

func timer(w http.ResponseWriter, r *http.Request) {

    conn, err := upgrader.Upgrade(w, r, nil)
    id++
    localID := id
    fmt.Println("Connected to: ", r.RemoteAddr, " as client # ", localID)
    fmt.Println(localID, r.UserAgent())
    if err != nil {
        fmt.Println("Error: ", err.Error())
    }

    for {

        time.Sleep(time.Second)
        now := time.Now()

        msg := "(" + strconv.Itoa(localID) + ") " + now.String()[:19]
        // Write time to browser
        err = conn.WriteMessage(websocket.TextMessage, []byte(msg))
        if err != nil {
            fmt.Println("Closed client # ", localID, ": Error: ", err.Error())
            return
        }
    }
}

Then run it and in the browser open

http://localhost:1234

You can open many tabs, or open many browsers or clients, and note that timer function will be instantiated with every client and it keeps working, which means every client will have it’s own running timer function, until the browser disconnects, then it will exist and will be removed from memory

Reference: https://gowebexamples.com/websockets/

ServiceCkeck

ServiceCheck is a native Linux 64 bit utility to check background service and run it if it is not up.

Usage:

  1. Configure checklist.ini file in the same directory of servicecheck application. Put all services to be checked in that file in the format

app1name      "/home/user/app1/app1name"
appn2name "sh /home/user/app2/app2.sh"


Application name (that appear in Linux processes (ps -ef)), then script to run the application if it is closed

2. Put servicecheck in crontab job to work periodiacly, for example every 5 minutes, e.g.

*/5 * * * * /home/user/checker/servicecheck

Note: to run applications in sudo privilege configure servicecheck in sudo crontab, for normal user, use crontal for normal user


CouchDB

Apache CouchDB is an open source NoSQL document based database engine that is written in Erlang. It uses RESTFull web service to be accessed for clients, so that you can use it though REST api or through drivers in each programming languages that has encapsulated REST calls into programming language methods/procedures calls.

CouchDB supports multi node clustering.

Installation

To install latest version of couchdb it in Ubuntu 16.04 (xenial):

echo "deb https://apache.bintray.com/couchdb-deb xenial main" | sudo tee -a /etc/apt/sources.list

For Ubuntu 18.04 (bionic):

echo "deb https://apache.bintray.com/couchdb-deb bionic main" | sudo tee -a /etc/apt/sources.list

Then add that new repository key:

curl -L https://couchdb.apache.org/repo/bintray-pubkey.asc | sudo apt-key add -

Note that if curl command is not found, you need to install it:

sudo apt-get install curl

Then update and install:

sudo apt-get update && sudo apt-get install couchdb

After installation, type this URL in browser to open administrative portal for CouchDB:

http://127.0.0.1:5984/_utils

Enter admin login and password that you have entered during installation, then you will get this view:

Then you can create databases, manage data, and users

REST API

Accessing server information :

curl http://127.0.0.1:5984/

Result:

{   
"couchdb": "Welcome", "version": "2.3.0", "git_sha": "07ea0c7",
"uuid": "8e99e2abff3f90efd7643ff8e04f7f8f",
"features": [ "pluggable-storage-engines", "scheduler" ],
"vendor": { "name": "The Apache Software Foundation" }
}

Creating a database named test :

curl -X PUT http://127.0.0.1:5984/test
result:
{"ok": true}

Retrieve information about the test database :

curl http://127.0.0.1:5984/test
result:

{ "db_name": "test", "purge_seq": "0-g1AAAAFTeJzLYWBg4MhgTmEQTM4vTc5ISXIwNDLXMwBCwxygFFMeC5BkeACk_gNBViIDQbUHIGrvE6N2AUTtfvxqkxyAZFI8QfuTFEDq7Il0ZwPE7vkEzEwAmVlP0MxEhiR5iKIsAD6cXo4", "update_seq": "1-g1AAAAFTeJzLYWBg4MhgTmEQTM4vTc5ISXIwNDLXMwBCwxygFFMiQ5L8____sxIZ8ChKUgCSSfZgdYz41DmA1MUTNi8BpK6eoLo8FiDJ0ACkgErnE6N2AUTtfmLUHoCovU-M2gcQtSD3ZgEAX4Rejw", "sizes": { "file": 38120, "external": 40, "active": 318 }, "other": { "data_size": 40 }, "doc_del_count": 0, "doc_count": 1, "disk_size": 38120, "disk_format_version": 7, "data_size": 318, "compact_running": false, "cluster": { "q": 8, "n": 1, "w": 1, "r": 1 }, "instance_start_time": "0" }

Create a document, asking CouchDB to supply a document id :


curl -X POST -H "Content-Type: application/json" --data \ '{ "text" : "Wikipedia on CouchDB", "rating": 5 }' \ http://127.0.0.1:5984/wiki

result:
{
"ok": true,
"id": "123BAC",
"rev": "946B7D1C"
}

Reference:

https://en.wikipedia.org/wiki/Apache_CouchDB

Go lang connection

First you need to import a library, for example:

https://github.com/rhinoman/couchdb-go

And this is an example of creating and connecting to a database called (academy) using Go language:

It contains create database, insert document, and search for documents:

// CouchDBSample project main.go
package main
import (
	"encoding/json"
	"fmt"
	"time"
	"github.com/rhinoman/couchdb-go"
)
type TestDocument struct {
	Name          string
	Address       string
	InsertionTime time.Time
}
type DataList struct {
	Docs []TestDocument
}
func main() {
	var timeout = time.Duration(500 * time.Millisecond)
	conn, err := couchdb.NewConnection("127.0.0.1", 5984, timeout)
	if err != nil {
		println("Error: ", err.Error())
	}
	auth := couchdb.BasicAuth{Username: "motaz", Password: "help"}
	conn.CreateDB("academy", &auth)
	db := conn.SelectDB("academy", &auth)
	today := time.Now()
	theDoc := TestDocument{
		Name:          "Motaz",
		Address:       "Alsajana",
		InsertionTime: today,
	}
	insert(db, theDoc)
	selector := `{"Address":"Bahri"}`
	search(db, selector)
}

func insert(db *couchdb.Database, theDoc TestDocument) {

	now := time.Now()
	rev, err := db.Save(theDoc, now.String(), "")
	if err != nil {
		println("Error in .Save: ", err.Error())
	} else {
		println("Saved: ", rev)
	}
}

func search(db *couchdb.Database, selector string) {
	result := DataList{}
	var selectorObj interface{}
	err := json.Unmarshal([]byte(selector), &selectorObj)
	params := couchdb.FindQueryParams{Selector: &selectorObj}
	err = db.Find(&result, &params)
	if err != nil {
		println("Error in .Find: ", err.Error())
	}
	fmt.Println("Num: ", len(result.Docs))
	for _, x := range result.Docs {
		fmt.Println("%v", x)
	}
}

Comparison to MangoDB

Advantages over MongoDB:

  1. Its license is Apache free license, while MongoDB needs commercial license for close source application, otherwise you have to open source your projects that uses MongoDB, so that MongoDB has been dropped from famous Linux distributions such as: Debian and RedHat.
  2. Uses REST API that can be called from any programming language, or scripts, such as shell script, no driver is needed when using this method
  3. Available in Android and IOS
  4. Supports master to master clustering in addition to master to slave clustering

Disadvantages of CouchDB compared to MongoDB:

  1. Less popular in usage compared to MongoDB
  2. MongoDB is more faster in read
  3. MongoDB is better in rapid growth databases
  4. MongoDB supports more programming languages

Sources:

https://db-engines.com/en/system/CouchDB%3BMongoDB

https://blog.panoply.io/couchdb-vs-mongodb