func (s *Server) protocol(conn InstConn) error { dec := conn.Decoder() defer func() { num := conn.StreamNum() s.lck.Lock() if _, found := s.connections[num]; found { delete(s.connections, num) } s.lck.Unlock() conn.Close() log.DebugLevel().Tag("server", "gormethods", "protocol").Println("protocol close") }() for { s.lck.Lock() connection, found := s.connections[conn.StreamNum()] if !found { connection = &Connection{} s.connections[conn.StreamNum()] = connection } connection.ttl = time.Now().Add(s.Ttl) connection.conn = conn s.lck.Unlock() var req msgtypes.MessageType // se fechar a conn do outro lado deve acontecer um err aqui err := dec.Decode(&req) if e.Find(err, io.EOF) >= 0 { return e.Forward(err) } else if err != nil { log.DebugLevel().Tag("server", "gormethods").Printf("Decode %v -> %v (%v) error: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), e.Trace(e.Forward(err))) return e.Forward(err) } switch req { case msgtypes.Call: err = s.protoCall(conn) if e.Find(err, ErrWire) >= 0 { return e.Forward(err) } case msgtypes.Destroy: err = s.protoDestroy(conn) if e.Find(err, ErrWire) >= 0 { return e.Forward(err) } return nil case msgtypes.Channel: err = s.protoChannel(conn) if e.Find(err, ErrWire) >= 0 { return e.Forward(err) } return nil default: log.ProtoLevel().Tag("server", "gormethods").Printf("Protocol fail from %v -> %v (%v) sent: %v", conn.RemoteAddr(), conn.LocalAddr(), conn.StreamNum(), req) } } }
func (m *Monitor) ping() (resp chan error) { resp = make(chan error) go func() { log.DebugLevel().Printf("Pinging %v", m.Name) start := time.Now() err := ping.PingRawUrl(m.Url) if err != nil { log.Errorf("Ping failed for %v with error: %v", m.Name, e.Trace(e.Forward(err))) resp <- e.Forward(err) return } log.DebugLevel().Printf("Ping ok for %v (%v)", m.Name, time.Since(start)) resp <- nil }() return }
func (t *TestExportClient) log(args ...interface{}) { _s_ := fmt.Sprint(args) _pc_, _, _, ok := runtime.Caller(1) if ok { _f_ := runtime.FuncForPC(_pc_) if t.client == nil { log.DebugLevel().Tag("gormethods", "client").Printf("%v: %v", _f_.Name(), _s_) return } log.DebugLevel().Tag("gormethods", "client").Printf("%v (%v, %v): %v", _f_.Name(), t.client.SessionName, t.client.InstanceName, _s_) return } if t.client == nil { log.DebugLevel().Tag("gormethods", "client").Printf("%v", _s_) return } log.DebugLevel().Tag("gormethods", "client").Printf("(%v, %v): %v", t.client.SessionName, t.client.InstanceName, _s_) }
func (c *client) Call(method string, args, retvals []reflect.Value) (err error) { start := time.Now() log.ProtoLevel().Tag("gormethods", "client", "call").Printf("Start call to %v %v %v", c.SessionName, c.InstanceName, method) defer func() { log.ProtoLevel().Tag("gormethods", "client", "call").Printf("Call to %v %v %v returned after %v with error: %v", c.SessionName, c.InstanceName, method, time.Since(start), err) }() conn, err := c.clones.Request(c.session, c.InstanceName) if err != nil { return e.Forward(err) } defer func() { if err != nil { log.ErrorLevel().Tag("client", "gormethods").Printf("Call to %v %v %v returned an error: %v", c.SessionName, c.InstanceName, method, err) conn.Close() return } er := c.clones.Return(c.SessionName, c.InstanceName, conn) if er != nil { log.DebugLevel().Tag("client", "gormethods").Println("Can't returns object:", e.Trace(e.Forward(er))) } }() conn.Mutex().Lock() defer conn.Mutex().Unlock() enc := conn.Encoder() dec := conn.Decoder() if c.ConnTimeout > 0 { err = conn.SetWriteDeadline(time.Now().Add(c.ConnTimeout)) if err != nil { return e.Forward(err) } } err = enc.Encode(msgtypes.Call) if err != nil { return e.Forward(err) } if c.ConnTimeout > 0 { err = conn.SetWriteDeadline(time.Now().Add(c.ConnTimeout)) if err != nil { return e.Forward(err) } } // Substituir os channels por uma representação destes chs := mkChClient(args) err = enc.Encode(&reqCall{ Method: method, Args: args, }) if err != nil { return e.Forward(err) } if len(chs) > 0 { err = recvInstance(dec, chs) if err != nil { return e.Forward(err) } // conn err = c.setupConn(chs) if err != nil { return e.Forward(err) } // gorotine c.startGorotineCh(chs) } // Olhar os args e descobrir quem é channel // Cada channel tem que corresponder a uma nova instancia // uma nova conn tem que ser pedida com isso: // conn, err := c.clones.Request(c.session, c.InstanceName) // Procurar por channels nos argumentos // Fazer setup de um ? e deixar uma gorotine fazendo esperando lá até o canal fechar if c.ConnTimeout > 0 { err = conn.SetWriteDeadline(time.Time{}) if err != nil { return e.Forward(err) } err = conn.SetReadDeadline(time.Now().Add(c.ConnTimeout)) if err != nil { return e.Forward(err) } } resp := respCall{} err = dec.Decode(&resp) if err != nil { return e.Forward(err) } if c.ConnTimeout > 0 { err = conn.SetReadDeadline(time.Time{}) if err != nil { return e.Forward(err) } } if resp.Err != nil { return e.Forward(resp.Err) } err = resp.Retvals(c, retvals) if err != nil { return e.Forward(err) } return }
func main() { println("Starting monlite...") // Configuration var opts options _, err := flags.Parse(&opts) if err != nil { log.Fatal("can't parse the command line options:", err) } cfg, err := ini.Load(opts.Conf) if err != nil { log.Fatal("Error reading configuratio file:", opts.Conf) } // Log stuff println("Log...") name := appname pid := os.Getpid() pidstr := strconv.FormatInt(int64(pid), 10) name = name + " (" + pidstr + ")" fnull, err := os.OpenFile("/dev/null", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660) if err != nil { log.Fatal("open log file failed:", err) } defer fnull.Close() stderrBack := log.NewWriter(fnull).F(log.DefFormatter) if opts.Level != "" && opts.Level != "nolog" { level, err := log.ParseLevel(opts.Level) if err != nil { log.Fatal("Invalid log level.") } stderrBack = log.Filter( log.NewWriter(os.Stderr).F(log.DefFormatter), log.Op(log.Ge, "level", level), ) } logfile := cfg.Section("log").Key("file").MustString("/var/log/monlite.log") if opts.Log != "" { logfile = opts.Log } loglevel := cfg.Section("log").Key("level").MustString("debug") level, err := log.ParseLevel(loglevel) if err != nil { log.Fatal("Invalid log level.") } var fileBack log.LogBackend if logfile != "" { f, err := os.OpenFile(logfile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660) if err != nil { log.Fatalf("open log file %v failed: %v", logfile, err) } defer f.Close() fileBack = log.Filter( log.NewWriter(f).F(log.DefFormatter), log.Op(log.Ge, "level", level), ) } log.Log = log.New(stderrBack, true).Domain(name).InfoLevel() if fileBack != nil { log.Log = log.New( log.NewMulti( stderrBack, log.DefFormatter, fileBack, log.DefFormatter, ), true, ).Domain(name).InfoLevel() } log.Println("Log Ok!") dns.SetLookupHostFunction(net.LookupHost) log.Println("Configuration...") cfgMail := cfg.Section("mail") smtpTimeout, err := cfgMail.Key("timeout").Int() if err != nil { log.Fatal("invalid smtp timeout") } server := cfgMail.Key("smtp").String() s := strings.Split(server, ":") if len(s) > 0 { server = s[0] } auth := smtp.PlainAuth( "", cfgMail.Key("account").String(), cfgMail.Key("password").String(), server, ) hostname := "your system" if hn, err := os.Hostname(); err == nil { hostname = hn } mons := make([]*monlite.Monitor, 0) for _, sec := range cfg.Sections() { if !strings.HasPrefix(sec.Name(), "service.") { continue } name := strings.TrimPrefix(sec.Name(), "service.") log.DebugLevel().Printf("Adding monitor %v for url: %v", name, sec.Key("url").String()) to, err := sec.Key("timeout").Int() if err != nil { log.Fatalf("invalid value in timeout for %v", name) } p, err := sec.Key("periode").Int() if err != nil { log.Fatalf("invalid value in timeout for %v", name) } sleep, err := sec.Key("sleep").Int() if err != nil { log.Fatalf("invalid value in sleep for %v", name) } fails, err := sec.Key("fails").Int() if err != nil { log.Fatalf("invalid value in fails for %v", name) } mons = append(mons, &monlite.Monitor{ Name: name, Url: sec.Key("url").String(), Timeout: time.Duration(to) * time.Second, Periode: time.Duration(p) * time.Second, Sleep: time.Duration(sleep) * time.Second, Fails: fails, OnFail: func(m *monlite.Monitor) error { body := "Mime-Version: 1.0\n" body += "Content-Type: text/plain; charset=utf-8\n" body += "From:" + cfgMail.Key("from").String() + "\n" body += "To:" + cfgMail.Key("to").String() + "\n" body += "Subject: [" + hostname + "] " + "Monitor fail for " + m.Name + "\n" body += "Hi! This is " + hostname + ".\n\n" body += "Monitor fail for " + m.Name + " " + m.Url + "\n\n" body += "Tank you, our lazy boy.\n" body += time.Now().Format(time.RFC1123Z) err := mysmtp.SendMail( cfgMail.Key("smtp").String(), auth, cfgMail.Key("from").String(), []string{cfgMail.Key("to").String()}, cfgMail.Key("helo").String(), []byte(body), time.Duration(smtpTimeout)*time.Second, false, ) if err != nil { return e.Forward(err) } return nil }, OnUnFail: func(m *monlite.Monitor) error { body := "Mime-Version: 1.0\n" body += "Content-Type: text/plain; charset=utf-8\n" body += "From:" + cfgMail.Key("from").String() + "\n" body += "To:" + cfgMail.Key("to").String() + "\n" body += "Subject: [" + hostname + "] " + "Monitor ok for " + m.Name + "\n" body += "Hi! This is " + hostname + ".\n\n" body += "Monitor ok for " + m.Name + " " + m.Url + "\n\n" body += "Tank you, our lazy boy.\n" body += time.Now().Format(time.RFC1123Z) err := mysmtp.SendMail( cfgMail.Key("smtp").String(), auth, cfgMail.Key("from").String(), []string{cfgMail.Key("to").String()}, cfgMail.Key("helo").String(), []byte(body), time.Duration(smtpTimeout)*time.Second, false, ) if err != nil { return e.Forward(err) } return nil }, }) } log.Println("Starting monitors...") for _, m := range mons { err := m.Start() if err != nil { log.Fatalf("Failed to start monitor for %v. Error: %v", m.Name, err) } } log.Println("Monitors ok!") sig := make(chan os.Signal) signal.Notify(sig, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM) <-sig log.Println("Stop monitors...") for _, m := range mons { log.DebugLevel().Printf("Stop monitor %v", m.Name) err := m.Stop() if err != nil { log.Errorf("Failed to start monitor for %v. Error: %v", m.Name, err) } } log.Println("End.") }