Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "database/sql"
- "fmt"
- _ "github.com/go-sql-driver/mysql" //можно подключить любую sql базу данных
- "log"
- "net"
- "net/smtp"
- "strings"
- "time"
- )
- var DB *sql.DB
- //Создаём счётчики
- var i_debug int = 1
- var i_info int = 1
- var i_warn int = 1
- var i_error int = 1
- //переменные которые выполняют роль кеша.
- var cacheDebug string
- var cacheInfo string
- var cacheWarn string
- var cacheError string
- //Здесь просто конектимся к бд
- func init() {
- db, err := sql.Open("mysql", "root:parsh888@/logs_service")
- if err != nil {
- log.Fatal(err)
- }
- DB = db
- }
- func main() {
- //вешаем сервер на 2000 порт
- l, err := net.Listen("tcp", ":2000")
- if err != nil {
- log.Fatal(err)
- }
- defer l.Close()
- for {
- //В вечном цикле "слушаем" 2000 порт. Ждём подключения
- conn, err := l.Accept()
- if err != nil {
- log.Fatal(err)
- }
- //К нам кто то подключился. Откроем для него свою GO рутину
- go func(c net.Conn) {
- //создаём буфер для получения данных из вне.
- buf := make([]byte, 1024)
- //открываем ещё один вечный цикл для того чтобы можно было получить n количество сообщений,
- // а не одно
- for {
- //Полученную информацию пишем в буфер
- c.Read(buf)
- //Конвертируем данные из буфера в строку и эти данные разбиваем по символам |][|
- //это нужно что бы отличить команду от логируемой записи.
- /*
- Пример работы с лог сервером
- telnet localhost 2000
- Debug|][|это тестовая лог запись
- Запись попадёт в бд как только мы обратимся к методу
- UnloadTheCacheDB|][|null
- или вы напишете 300 Debug логов. В бд уйдёт сразу пачка.
- */
- result := strings.Split(string(buf), "|][|")
- //отправляем команды в swith (команда это лово перед |][|). Если команда существует
- //то сервер её обработает. Если нет то произойдёт вызов swith default и соединение
- //закроется
- switch result[0] {
- case "Debug":
- if i_debug <= 300 { //Как только соберётся 300 лог записей отработает это условие
- //этот кусок запроса последний в пачке. Прикрутил else из - за того что если за
- // последними данными будет кома то бд скажет об ошибке sql синтаксиса
- cacheDebug = cacheDebug + "('" + time.Now().String() + "','" + result[1] + "')"
- //Передаём наш кеш в новую GO рутину
- go DebugDB(cacheDebug)
- //сбрасываем счётчик
- i_debug = 0
- //очищаем кеш
- cacheDebug = " "
- } else {
- //если эти данные не последние то за ними нужна кома.
- cacheDebug = cacheDebug + "('" + time.Now().String() + "','" + result[1] + "'),"
- }
- //обновляем счётчик
- i_debug++
- //Дальше код до case Fatal аналогичен.
- case "Info":
- if i_info <= 150 {
- cacheInfo = cacheInfo + "('" + time.Now().String() + "','" + result[1] + "')"
- go InfoDB(cacheInfo)
- i_info = 0
- cacheInfo = " "
- } else {
- cacheInfo = cacheInfo + "('" + time.Now().String() + "','" + result[1] + "'),"
- }
- i_info++
- case "Warn":
- if i_warn <= 50 {
- cacheWarn = cacheWarn + "('" + time.Now().String() + "','" + result[1] + "')"
- go WarnDB(cacheWarn)
- i_warn = 0
- cacheWarn = " "
- } else {
- cacheWarn = cacheWarn + "('" + time.Now().String() + "','" + result[1] + "'),"
- }
- i_warn++
- case "Error":
- if i_error == 25 {
- cacheError = cacheError + "('" + time.Now().String() + "','" + result[1] + "')"
- go ErrorDB(cacheError)
- i_error = 0
- cacheError = " "
- cacheError = cacheError + "('" + time.Now().String() + "','" + result[1] + "'),"
- }
- i_error++
- //фатальная ошибка. Буфера нет. Сразу пишется в бд и отправляется уведомления на email
- case "Fatal":
- go FatalDB(result[1])
- //Отправляем все записи в бд не дождавшись пока наполняться буферы
- case "UnloadTheCacheDB":
- //Отправляем буферы в новые go рутины
- go DebugDB(cacheDebug)
- go InfoDB(cacheInfo)
- go WarnDB(cacheWarn)
- go ErrorDB(cacheError)
- //чистим кешы
- cacheDebug = " "
- cacheInfo = " "
- cacheWarn = " "
- cacheError = " "
- //сбрасываем щётчики
- i_debug = 0
- i_info = 0
- i_warn = 0
- i_error = 0
- log.Print("Бд успешно обновлена, а кеш очищен")
- //этот метод безвозвратно удаляет логи из буфера.
- case "ClearCache":
- cacheDebug = " "
- cacheInfo = " "
- cacheWarn = " "
- cacheError = " "
- i_debug = 0
- i_info = 0
- i_warn = 0
- i_error = 0
- log.Print("Кеш успешно очистили")
- //метода нету. Закрываем соеденение
- default:
- log.Print("case Default\n")
- c.Close()
- //если убрать return то log.Print будет работать в бесконечном цикле
- return
- }
- }
- }(conn)
- }
- }
- //просто пише в таблицы.
- func DebugDB(cache string) {
- DB.Exec("INSERT INTO debug (date,message) VALUES " + cache)
- return
- }
- func InfoDB(cache string) {
- DB.Exec("INSERT INTO info (date,message) VALUES " + cache)
- return
- }
- func WarnDB(cache string) {
- DB.Exec("INSERT INTO warn (date,message) VALUES " + cache)
- return
- }
- func ErrorDB(cache string) {
- DB.Exec("INSERT INTO error (date,message) VALUES " + cache)
- return
- }
- //А тут пишем в бд и отправляем email уведомление
- func FatalDB(message string) {
- //пишем в бд
- DB.Exec("INSERT INTO fatal (date,message) VALUES (?,?)", time.Now().String(), message)
- ////Уведомление
- conf := map[string]string{
- "username": "portalnet.tk@gmail.com", //логин от любой почты на gamail
- "password": "parsh888", //ну и пароль
- "host": "smtp.gmail.com",
- "port": "587",
- }
- //масив с адресатами
- to := []string{
- "v.grabko99@gmail.com",
- "id324237193-6fce7d7ef@vkmessenger.com",
- }
- //вызиваем отправку
- SendMail(conf, to, "Fatal Errors", message)
- return
- }
- func SendMail(conf map[string]string, to []string, subject string, msg string) {
- auth := smtp.PlainAuth(
- "",
- conf["username"],
- conf["password"],
- conf["host"],
- )
- address := fmt.Sprintf("%v:%v", conf["host"], conf["port"])
- body := []byte("Subject: " + subject + "\r\n\r\n" + msg)
- err := smtp.SendMail(
- address,
- auth,
- conf["username"],
- to,
- body,
- )
- if err != nil {
- log.Fatal(err)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement