Coletando métricas utilizando Go

Num projeto pessoal, me deparei com a necessidade de coletar métricas, tais como uso da CPU, uso do disco, uso da memória, etc. Além disso, em ambientes com uso intensivo dos recursos, essa coleta deve impactar o menos possível no desempenho geral do sistema. A primeira opção, portanto, é utilizar C. Porém, resolvi dar uma chance à linguagem Go, do Google. Tendo uma comunidade bastante ativa, devido a idade da linguagem, não foi difícil achar um pacote que colete essas métricas, o gopsutil. Esse pacote é baseado no psutil, feito em Python.

O uso deste pacote é bastante simples, e a documentação pode ser obtida aqui.

Por exemplo, para pegar informações relativas a CPU:

package main

import (
"fmt"
"github.com/shirou/gopsutil/cpu"
)

func main() {
cpuInfo, _ := cpu.Info()
fmt.Printf("%v", cpuInfo)
}

O código acima, que importa o pacote gopsutil/cpu, resulta na imagem abaixo, que mostra uma série de informações sobre a CPU, por núcleo.

Imagem de um terminal mostrando um array na linguagem Go, com informações como vendorId, physicalId, modelName, mhz, cacheSize e outros. Cada item do array é uma thread da CPU

Para pegar informações específicas, como por exemplo, a de um núcleo específico da CPU, é só fazer isso (resto do código fica igual):

fmt.Printf("%v", cpuInfo[0])

Terminal do linux mostrando a execução do programa, mostrando um dos itens do array da imagem anterior, com cpu, vendorId, family, physicalId, coreId, cores, modelName, mhz, cacheSize, etc.

E por fim, pegar um campo específico, tal como o “ModelName”:

fmt.Printf("%v", cpuInfo[0].ModelName)

Terminal mostrando a execução do programa go run getCpu.go, que retorna "Intel Core i3-4005U CPU @ 1.70GHz"

Uma função bastante útil é o percentual em uso:

fmt.Printf("%v", cpu.Percent(time.Duration(1) * time.Second, false))

 

Essa função possui dois parâmetros, o intervalo de tempo no qual será observado, e se a consulta será por núcleo. Se o intervalo for igual a 0, a função calculará relativo a última execução dessa função (e portanto, na primeira execução, o resultado será 0, que deverá ser descartado). Para exemplificar o segundo parâmetro, primeiro vou mostrar a execução quando o parâmetro é false. Como pode-se ver, é um único resultado, que é a média de uso de todos as threads da CPU:

Terminal mostrando a execução de go run getCPU.go, que retorna 2.7499999, que é o uso da CPU.

Já quando o parâmetro é true, o resultado de cada thread é mostrado:

Terminal mostrando o programa go run getCPU.go, que retorna 4 itens em um array, que é o uso da CPU por thread.

 

As outras funções relativas a CPU podem ser obtidas aqui: https://godoc.org/github.com/shirou/gopsutil/cpu

Só pra mostrar outras funções desse pacote, uma métrica que eu considero interessante é o load, que mostra quantos processos estão enfileirados, esperando por recursos. Seu uso é bastante intuitivo:

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/load"
)

func main() {
    loadInfo, _ := load.Avg()

    fmt.Println("Load 1 min:",loadInfo.Load1)
    fmt.Println("Load 5 min:",loadInfo.Load5)
    fmt.Println("Load 15 min:",loadInfo.Load15)
}

Terminal mostrando a execução do programa go run getLoad.go, que retorna as métricas do load average do Linux: Load 1 min: 0.44 Load 5 min: 0.63 Load 15 min: 0.73

Esse pacote, simples e efetivo, não funciona somente no ambiente Linux. A ideia do mantenedor é que as funções funcionem em Unix-like, Windows, FreeBDS e outros.

Primeiras impressões com Elixir

Como consta no próprio site, Elixir é uma linguagem dinâmica e funcional, desenhada para construir aplicações escaláveis e de fácil manutenção. Ela foi criada pelo brasileiro José Valim que, insatisfeito com algumas coisas em Ruby, linguagem que utilizava em sua empresa, Plataformatec, pesquisou uma forma mais elegante de resolver certos problemas. Ele, então, começou a estudar Erlang (uma senhora linguagem, que roda no WhatsApp, como falei neste post), e resolveu criar o Elixir, que roda sobre a máquina virtual do Erlang (BEAM), com uma sintaxe mais “ruby-like”. Porém, para quem vem de uma linguagem com sintaxe estilo C, e seguindo os paradigmas procedural e orientado a objeto, o Elixir pode parecer estranho. Mas não se engane, por trás da sintaxe diferente, e de outra forma de pensar, existe uma linguagem poderosa, que tem ganhado bastante adeptos.

(mais…)

Let’s Encrypt – Por uma web mais segura

O Let’s Encrypt é um projeto mantido por diversas empresas do segmento de tecnologia, incluindo Facebook, Mozilla, Akamai e Cisco, que pretende melhorar a segurança na internet. Como? Através de certificados SSL/TLS grátis, autenticados, o que garante uma confiabilidade maior do que um certificado auto-gerado. Para entender um pouco melhor esta iniciativa, vamos recapitular o que são certificados TLS, principais empresas que fornecem, e vantagens (e desvantagens) do Let’s Encrypt, em relação a elas.

(mais…)

Roles e capabilities no WordPress

Roles, traduzidos para português como funções, é uma forma de fazer a autorização de usuários, isto é, garantir que determinado usuário tenha acesso a X funcionalidades, dependendo das suas necessidades. No WordPress, por padrão, são criados seis (6) funções: assinante, colaborador, autor,  editor, admin e super admin [1] (usado quando a função multisite está ativa).

(mais…)

O que algumas startups usam, em desenvolvimento? – WhatsApp

Sempre fui interessado em saber quais ferramentas (linguagens, frameworks, banco de dados) as grandes empresas usam, e principalmente, como escalam suas aplicações. Nesta primeira parte, vou abordar o WhatsApp (hoje uma empresa do grupo Facebook), que está presente em qualquer smartphone. Como eles conseguem? A resposta curta: Erlang.

(mais…)

Casos de uso de Node.js

nodejs-logo

Node.js, segundo o próprio site, é:

Node.js® is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

Traduzindo: é um framework baseado na engine (motor) V8 do Chrome, para rodar Javascript, para construir aplicações rápidas e escaláveis. É, portanto, um framework server-side. Um detalhe que chama a atenção é que o Node.JS é “não-bloqueante”. Para entender o que é isso, separei alguns links, aqui e aqui.

(mais…)