Skip to content

Commit

Permalink
add stauts
Browse files Browse the repository at this point in the history
  • Loading branch information
sigmonsays committed Jan 18, 2016
1 parent 5053ac1 commit 1ad1c61
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 0 deletions.
59 changes: 59 additions & 0 deletions cmd/runitcmd/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"fmt"
"os"
"text/tabwriter"

"github.com/codegangsta/cli"
)

func initList(app *Application) cli.Command {
description := "list services"
usage := "list services"

flags := []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "list all services",
},
}

cmd := cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: usage,
Description: description,
Flags: flags,
Action: app.List,
}
return cmd
}

func (app *Application) List(c *cli.Context) {
show_all := c.Bool("all")

log.Tracef("list all:%v", show_all)

services, err := app.Runit.ListServices()
if err != nil {
log.Warnf("ListServices: %s", err)
return
}

tw := new(tabwriter.Writer)
tw.Init(os.Stdout, 0, 8, 0, '\t', 0)
for _, service := range services {
if show_all == false && service.Enabled() == false {
continue
}
st, err := service.Status()
if err != nil {
log.Warnf("Status: %s: %s", service.Name, err)
continue
}
fmt.Fprintf(tw, "%s \t running:%v \t pid:%d \t sec:%d\n", service.Name, st.Running, st.Pid, st.Seconds)
}
tw.Flush()

}
11 changes: 11 additions & 0 deletions cmd/runitcmd/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
gologging "github.com/sigmonsays/go-logging"
)

var log gologging.Logger

func init() {
log = gologging.Register("runitcmd", func(newlog gologging.Logger) { log = newlog })
}
64 changes: 64 additions & 0 deletions cmd/runitcmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package main

import (
"os"

"github.com/codegangsta/cli"
"github.com/sigmonsays/runitcmd/runit"

gologging "github.com/sigmonsays/go-logging"
)

type Application struct {
*cli.App
Runit *runit.Runit
}

func main() {
c := cli.NewApp()
c.Name = "runitcmd"
c.Version = "0.0.1"
app := &Application{
App: c,
}

rcfg := runit.DefaultRunitConfig()

app.Flags = []cli.Flag{
cli.StringFlag{
Name: "level, l",
Value: "WARN",
Usage: "change log level",
},
cli.StringFlag{
Name: "service-dir",
Usage: "change service dir",
},
cli.StringFlag{
Name: "active-dir",
Usage: "change active service dir",
},
}

app.Before = func(c *cli.Context) error {
gologging.SetLogLevel(c.String("level"))

service_dir := c.String("service-dir")
active_dir := c.String("active-dir")
if service_dir != "" {
rcfg.ServiceDir = service_dir
}
if active_dir != "" {
rcfg.ActiveDir = active_dir
}
app.Runit = runit.NewRunit(rcfg)

return nil
}

app.Commands = []cli.Command{
initList(app),
}

app.Run(os.Args)
}
59 changes: 59 additions & 0 deletions runit/runit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package runit

import (
"os"
"path/filepath"
)

func DefaultRunitConfig() *RunitConfig {
return &RunitConfig{
ServiceDir: "/etc/sv",
ActiveDir: "/etc/service",
}
}

type RunitConfig struct {
ServiceDir string
ActiveDir string
}

func NewRunit(cfg *RunitConfig) *Runit {
if cfg == nil {
cfg = DefaultRunitConfig()
}
return &Runit{
ServiceDir: cfg.ServiceDir,
ActiveDir: cfg.ActiveDir,
}
}

type Runit struct {
ServiceDir string
ActiveDir string
}

func (runit *Runit) ListServices() ([]*Service, error) {

f, err := os.Open(runit.ServiceDir)
if err != nil {
return nil, err
}
defer f.Close()

names, err := f.Readdirnames(-1)
if err != nil {
return nil, err
}

services := make([]*Service, 0)
for _, name := range names {
s := &Service{
ServiceDir: filepath.Join(runit.ServiceDir, name),
ActiveDir: filepath.Join(runit.ActiveDir, name),
Name: name,
}
services = append(services, s)
}

return services, nil
}
106 changes: 106 additions & 0 deletions runit/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package runit

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
)

type Status int

const (
StatusInvalid Status = iota
StatusUp
StatusDown
)

const svTimeMod = 4611686018427387914

func svNow() uint64 {
return uint64(svTimeMod + time.Now().Unix())
}

type ServiceStatus struct {
Enabled bool
Running bool
Pid int
Seconds int64
}

type Service struct {
ActiveDir string
ServiceDir string
Name string
}

func (s *Service) String() string {
return fmt.Sprintf("service(name=%s dir=%s/%s)", s.Name, s.ActiveDir, s.ServiceDir)
}

func (s *Service) Enabled() bool {
_, err := os.Stat(s.ActiveDir)
if err == nil {
return true
}
return false
}

func (s *Service) Running() bool {
statfile := filepath.Join(s.ActiveDir, "supervise/stat")
data, err := ioutil.ReadFile(statfile)
if err != nil {
return false
}

stat := strings.TrimRight(string(data), "\n")
if stat == "run" {
return true
}
return false

}

func (s *Service) Status() (*ServiceStatus, error) {
st := &ServiceStatus{
Enabled: s.Enabled(),
Running: s.Running(),
}

statusfile := filepath.Join(s.ActiveDir, "supervise/status")

status, err := ioutil.ReadFile(statusfile)
if err != nil {
return nil, err
}

pid := uint(status[15])
pid <<= 8
pid += uint(status[14])
pid <<= 8
pid += uint(status[13])
pid <<= 8
pid += uint(status[12])
st.Pid = int(pid)

t := uint64(status[0])
t <<= 8
t += uint64(status[1])
t <<= 8
t += uint64(status[2])
t <<= 8
t += uint64(status[3])
t <<= 8
t += uint64(status[4])
t <<= 8
t += uint64(status[5])
t <<= 8
t += uint64(status[6])
t <<= 8
t += uint64(status[7])
st.Seconds = int64(svNow() - t)

return st, nil
}

0 comments on commit 1ad1c61

Please sign in to comment.