Пример #1
0
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)
		}
	}
}
Пример #2
0
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
}
Пример #3
0
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_)
}
Пример #4
0
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
}
Пример #5
0
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.")
}