Go, go, go ... First impressions

    Weekday evening, how not to write article articles. In which I want to share my impressions of getting to know Go . All that is written below is the subjective opinion of the author. This article will be useful to those who want to sit down for learning Go and will prove to be of little use for developers on it.


    Background


    The main kind of my activity is solving business problems in a harsh enterprise environment in java , and by nature I want to learn new and interesting things, to support skills, learn new things and not stand still (a kind of linear-> businessman ). And for this reason, the docker gaze has long fallen .


    And now on the current project, in places I began to implement docker practices in the environment of developers and testers. And where there docker , appear on containers, these containers would like to know everything from the CPU to the Network I of / About . For all this, I first used the standard bunch docker psand docker stats. There were some inconveniences due to the fact that these are two separate utilities, but overall it was sleepy until I came across ctop . I think many who use docker are familiar with it.


    Project




    Running ctop on the machine, I saw beautiful like-htop containers with statistics and the ability to see detailed information on the container, with search or sorting. In general, I was extremely pleased.


    Until a certain point, the first thing I would like to see in ctop is the healthcheck of the container, but it was not there. Then docker swarm mode surfaced and for which I would also like to see statistics on services from ctop .
    And here the corrosive reader may wonder, but where does Go , if everything is about dockerand personal opinion of the author.


    Having the experience of writing / finishing Linux utilities for myself, I thought, well, since this is in the terminal and this is for the console, it means there should be python and now we’ll quickly add whatever you want.


    When I went into the repository , I was surprised to see Go there (although logically, docker is written on it). Remembering someone’s words from the report about Go that it can be learned in the evening, he continued his undertakings in finalizing the program. After reading the documentation and running examples from this site, I sat down for the project.


    Code examples


    When meeting Go, a phrase slipped somewhere that it was “concise and easy to support,” and I would agree with this statement.


    The first thing that looked unusual but comfortable was GOPATH . About the setup and the concepts themselves are very well described here .


    An approach to organizing and structuring packages and the level of access also seemed interesting. In particular, the declaration of public and private methods through capital and lowercase letters and the implementation of interfaces. And he was incredibly pleased with the signs, like a person from the java world .


    Dependency management, at least on this project, did not cause any special difficulties (although Go was scolded for lack of a package manager). Everything that is indicated in the construction importis collected in the GOPATH folder in the scr directory and the dependencies can already be used. Separately, it is worth noting that the dependency can be directly on the project with GitHub and it does not differ much from the dependency on some own module (import logic is minimized):


    import (
        "fmt"
        "strings"
        "sync"
        "github.com/bcicen/ctop/connector/collector"
        api "github.com/fsouza/go-dockerclient"
        "github.com/bcicen/ctop/config"
        "context"
        "github.com/bcicen/ctop/entity"
        "github.com/docker/docker/api/types/swarm"
    )

    As for ctop - it turned out to be quite simple in its structure, for which special thanks to its miner.


    The structure of the project is divided into three large parts:


    • connector
    • cwidgets
    • grid / cursor

    connector - an interface for connecting to different services provided information about containers. For example, docker, opencontainer, kubernates and others.


    A class has been created in the connector directory main.go, which describes the interface of our connector:


    package connector
    type Connector interface {
        All() container.Containers
        Get(string) (*container.Container, bool)
    }

    And in order to implement it, we need to create another file, for example docker.go, for the method, NewDocker()specify the return type of the interface and return the address for it.
    And then implement all of the above methods. I liked that within the framework of one class, several implementations of the interface can be described and this is normal practice.


    package docker
    type Docker struct {
        client       *api.Client
        containers   map[string]*container.Container
        needsRefresh chan string
        lock         sync.RWMutex
    }
    func NewDocker() Connector {
        client, err := api.NewClientFromEnv()
        if err != nil {
        panic(err)
        }
        cm := &Docker{
        client:       client,
        containers:   make(map[string]*container.Container),
        needsRefresh: make(chan string, 60),
            lock:         sync.RWMutex{},
        }
        return cm
    }
    func (cm *Docker) All() (containers container.Containers) {
        cm.lock.Lock()
        for _, c := range cm.containers {
            containers = append(containers, c)
        }
        containers.Sort()
        containers.Filter()
        cm.lock.Unlock()
        return containers
    }
    func (cm *Docker) Get(id string) (*container.Container, bool) {
        cm.lock.Lock()
        c, ok := cm.containers[id]
        cm.lock.Unlock()
        return c, ok
    }

    In brackets after it is funcindicated for which structure the method is implemented, it looks very convenient.


    cwidgets - individual graphic elements from which the finished interface is assembled.
    grid / cursor - a package that collects everything together for display and provides access and control methods.


    The healthcheck mapping implementation was pretty simple. They docker.goadded an attribute healthto the meta information, which we read through api similarly to the functional . And depending on the value, change the color of the text in the column .docker inspect NAME


    But the addition of swarm mode turned out to be more interesting.


    In swarm mode , concepts appear node, serviceand task. And between them it is necessary to display the relationship, who is where. And this was not provided for in ctop . And here I really felt good code support. The structure of the container contained methods for accessing meta information and a graphical interface, which can easily be moved to a separate interface, which is what is needed for the newly introduced concepts. The interface looks like this:


    package entity
    import (
        "github.com/bcicen/ctop/logging"
        "github.com/bcicen/ctop/connector/collector"
        "github.com/bcicen/ctop/models"
    )
    var (
        log = logging.Init()
    )
    type Entity interface {
        SetState(s string)
        Logs() collector.LogCollector
        GetMetaEntity() Meta
        GetId() string
        GetMetrics() models.Metrics
    }

    Here we declare a common variable for all classes implementing this interface logand describe the interface contract: the method of changing the state of an element, access to the log of a specific element through a variable log, access to the meta information of the element and access to its metrics.


    After describing the interface, implementing it for all structures, and replacing the old containerwith a new one entityin the methods grid, one interesting question came up. Docker currently does not provide the ability to obtain information about the use of resources from a remote node using api tools . Therefore, I settled on the implementation of the output structure of the swarm cluster and healthcheck launched tasks.


    Impression and Conclusion


    In general, I was very pleased with the use of Go in the project, the language was really made practical and concise. He somehow reminded a mixture of Python and C ++ , from which they tried to take all the best. You can really learn it in an evening. But in order to start writing on it over the evening you need to have a sufficient background, and I would not recommend it as the first language for study. We must probably come to an understanding of its convenience. Also, for myself, I identified a niche for the language in the form of writing services (it was probably designed for this).


    As for ctop , the miner accepted the pull request with the healthcheck display, now I plan to finish the display of the swarm structure . I would be glad to suggest how to implement the reading of container metrics from remote nodes.

    Only registered users can participate in the survey. Please come in.

    Your opinion on Go

    • 31.7% I am writing, very satisfied 196
    • 8.2% I am writing, not very satisfied 51
    • 41.4% Didn’t write, but I want to start 256
    • 18.4% I did not write and I am not going to 114

    Also popular now: