Skip to content

Commit

Permalink
log level & syslog
Browse files Browse the repository at this point in the history
Co-Authored-By: Alireza Ahmadi <alireza7@gmail.com>
  • Loading branch information
MHSanaei and alireza0 committed Jul 31, 2023
1 parent c46ced0 commit bf97191
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 86 deletions.
114 changes: 67 additions & 47 deletions logger/logger.go
Original file line number Diff line number Diff line change
@@ -1,98 +1,118 @@
package logger

import (
"fmt"
"os"
"sync"
"time"

"github.com/op/go-logging"
)

var (
logger *logging.Logger
mu sync.Mutex
)
var logger *logging.Logger
var logBuffer []struct {
time string
level logging.Level
log string
}

func init() {
InitLogger(logging.INFO)
}

func InitLogger(level logging.Level) {
mu.Lock()
defer mu.Unlock()

if logger != nil {
return
newLogger := logging.MustGetLogger("x-ui")
var err error
var backend logging.Backend
var format logging.Formatter
ppid := os.Getppid()

if ppid == 1 {
backend, err = logging.NewSyslogBackend("")
format = logging.MustStringFormatter(
`%{level} - %{message}`,
)
}
if err != nil || ppid != 1 {
backend = logging.NewLogBackend(os.Stderr, "", 0)
format = logging.MustStringFormatter(
`%{time:2006/01/02 15:04:05} %{level} - %{message}`,
)
}

format := logging.MustStringFormatter(
`%{time:2006/01/02 15:04:05} %{level} - %{message}`,
)
newLogger := logging.MustGetLogger("x-ui")
backend := logging.NewLogBackend(os.Stderr, "", 0)
backendFormatter := logging.NewBackendFormatter(backend, format)
backendLeveled := logging.AddModuleLevel(backendFormatter)
backendLeveled.SetLevel(level, "")
newLogger.SetBackend(logging.MultiLogger(backendLeveled))
backendLeveled.SetLevel(level, "x-ui")
newLogger.SetBackend(backendLeveled)

logger = newLogger
}

func Debug(args ...interface{}) {
if logger != nil {
logger.Debug(args...)
}
logger.Debug(args...)
addToBuffer("DEBUG", fmt.Sprint(args...))
}

func Debugf(format string, args ...interface{}) {
if logger != nil {
logger.Debugf(format, args...)
}
logger.Debugf(format, args...)
addToBuffer("DEBUG", fmt.Sprintf(format, args...))
}

func Info(args ...interface{}) {
if logger != nil {
logger.Info(args...)
}
logger.Info(args...)
addToBuffer("INFO", fmt.Sprint(args...))
}

func Infof(format string, args ...interface{}) {
if logger != nil {
logger.Infof(format, args...)
}
logger.Infof(format, args...)
addToBuffer("INFO", fmt.Sprintf(format, args...))
}

func Warning(args ...interface{}) {
if logger != nil {
logger.Warning(args...)
}
logger.Warning(args...)
addToBuffer("WARNING", fmt.Sprint(args...))
}

func Warningf(format string, args ...interface{}) {
if logger != nil {
logger.Warningf(format, args...)
}
logger.Warningf(format, args...)
addToBuffer("WARNING", fmt.Sprintf(format, args...))
}

func Error(args ...interface{}) {
if logger != nil {
logger.Error(args...)
}
logger.Error(args...)
addToBuffer("ERROR", fmt.Sprint(args...))
}

func Errorf(format string, args ...interface{}) {
if logger != nil {
logger.Errorf(format, args...)
}
logger.Errorf(format, args...)
addToBuffer("ERROR", fmt.Sprintf(format, args...))
}

func Notice(args ...interface{}) {
if logger != nil {
logger.Notice(args...)
func addToBuffer(level string, newLog string) {
t := time.Now()
if len(logBuffer) >= 10240 {
logBuffer = logBuffer[1:]
}

logLevel, _ := logging.LogLevel(level)
logBuffer = append(logBuffer, struct {
time string
level logging.Level
log string
}{
time: t.Format("2006/01/02 15:04:05"),
level: logLevel,
log: newLog,
})
}

func Noticef(format string, args ...interface{}) {
if logger != nil {
logger.Noticef(format, args...)
func GetLogs(c int, level string) []string {
var output []string
logLevel, _ := logging.LogLevel(level)

for i := len(logBuffer) - 1; i >= 0 && len(output) <= c; i-- {
if logBuffer[i].level <= logLevel {
output = append(output, fmt.Sprintf("%s %s - %s", logBuffer[i].time, logBuffer[i].level, logBuffer[i].log))
}
}
return output
}
5 changes: 2 additions & 3 deletions web/assets/js/model/xray.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ class HttpStreamSettings extends XrayCommonClass {
}

static fromJson(json={}) {
return new HttpStreamSettings(json.path, json.host, json.sockopt);
return new HttpStreamSettings(json.path, json.host);
}

toJson() {
Expand Down Expand Up @@ -461,8 +461,7 @@ class GrpcStreamSettings extends XrayCommonClass {
static fromJson(json={}) {
return new GrpcStreamSettings(
json.serviceName,
json.multiMode,
json.sockopt
json.multiMode
);
}

Expand Down
9 changes: 3 additions & 6 deletions web/controller/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,9 @@ func (a *ServerController) restartXrayService(c *gin.Context) {

func (a *ServerController) getLogs(c *gin.Context) {
count := c.Param("count")
logLevel := c.PostForm("logLevel")
logs, err := a.serverService.GetLogs(count, logLevel)
if err != nil {
jsonMsg(c, "getLogs", err)
return
}
level := c.PostForm("level")
syslog := c.PostForm("syslog")
logs := a.serverService.GetLogs(count, level, syslog)
jsonObj(c, logs, nil)
}

Expand Down
27 changes: 15 additions & 12 deletions web/html/xui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
<a-col :sm="24" :md="12">
<a-card hoverable :class="themeSwitcher.darkCardClass">
{{ i18n "menu.link" }}:
<a-tag color="blue" style="cursor: pointer;" @click="openLogs(logModal.rows, logModal.logLevel)">{{ i18n "pages.index.logs" }}</a-tag>
<a-tag color="blue" style="cursor: pointer;" @click="openLogs()">{{ i18n "pages.index.logs" }}</a-tag>
<a-tag color="blue" style="cursor: pointer;" @click="openConfig">{{ i18n "pages.index.config" }}</a-tag>
<a-tag color="blue" style="cursor: pointer;" @click="openBackup">{{ i18n "pages.index.backup" }}</a-tag>
</a-card>
Expand Down Expand Up @@ -253,7 +253,7 @@ <h2>{{ i18n "pages.index.xraySwitchClickDesk"}}</h2>
<a-form-item label="Count">
<a-select v-model="logModal.rows"
style="width: 80px"
@change="openLogs(logModal.rows, logModal.logLevel)"
@change="openLogs()"
:dropdown-class-name="themeSwitcher.darkCardClass">
<a-select-option value="10">10</a-select-option>
<a-select-option value="20">20</a-select-option>
Expand All @@ -262,9 +262,9 @@ <h2>{{ i18n "pages.index.xraySwitchClickDesk"}}</h2>
</a-select>
</a-form-item>
<a-form-item label="Log Level">
<a-select v-model="logModal.logLevel"
<a-select v-model="logModal.level"
style="width: 120px"
@change="openLogs(logModal.rows, logModal.logLevel)"
@change="openLogs()"
:dropdown-class-name="themeSwitcher.darkCardClass">
<a-select-option value="debug">Debug</a-select-option>
<a-select-option value="info">Info</a-select-option>
Expand All @@ -273,8 +273,11 @@ <h2>{{ i18n "pages.index.xraySwitchClickDesk"}}</h2>
<a-select-option value="err">Error</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="SysLog">
<a-checkbox v-model="logModal.syslog" @change="openLogs()"></a-checkbox>
</a-form-item>
<a-form-item>
<button class="ant-btn ant-btn-primary" @click="openLogs(logModal.rows, logModal.logLevel)"><a-icon type="sync"></a-icon> Reload</button>
<button class="ant-btn ant-btn-primary" @click="openLogs()"><a-icon type="sync"></a-icon> Reload</button>
</a-form-item>
<a-form-item>
<a-button type="primary" style="margin-bottom: 10px;"
Expand Down Expand Up @@ -409,11 +412,11 @@ <h2>{{ i18n "pages.index.xraySwitchClickDesk"}}</h2>
visible: false,
logs: '',
rows: 20,
logLevel: 'info',
show(logs, rows) {
level: 'info',
syslog: false,
show(logs) {
this.visible = true;
this.rows = rows;
this.logs = logs.join("\n");
this.logs = logs? logs.join("\n"): "No Record...";
},
hide() {
this.visible = false;
Expand Down Expand Up @@ -514,14 +517,14 @@ <h2>{{ i18n "pages.index.xraySwitchClickDesk"}}</h2>
return;
}
},
async openLogs(rows, logLevel) {
async openLogs(){
this.loading(true);
const msg = await HttpUtil.post('server/logs/' + rows, { logLevel: `${logLevel}` });
const msg = await HttpUtil.post('server/logs/'+logModal.rows,{level: logModal.level, syslog: logModal.syslog});
this.loading(false);
if (!msg.success) {
return;
}
logModal.show(msg.obj, rows);
logModal.show(msg.obj);
},
async openConfig() {
this.loading(true);
Expand Down
35 changes: 17 additions & 18 deletions web/service/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -378,28 +379,26 @@ func (s *ServerService) UpdateXray(version string) error {
return nil
}

func (s *ServerService) GetLogs(count string, logLevel string) ([]string, error) {
var cmdArgs []string
if runtime.GOOS == "linux" {
cmdArgs = []string{"journalctl", "-u", "x-ui", "--no-pager", "-n", count}
if logLevel != "" {
cmdArgs = append(cmdArgs, "-p", logLevel)
func (s *ServerService) GetLogs(count string, level string, syslog string) []string {
c, _ := strconv.Atoi(count)
var lines []string

if syslog == "true" {
cmdArgs := []string{"journalctl", "-u", "x-ui", "--no-pager", "-n", count, "-p", level}
// Run the command
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return []string{"Failed to run journalctl command!"}
}
lines = strings.Split(out.String(), "\n")
} else {
return []string{"Unsupported operating system"}, nil
}

cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return nil, err
lines = logger.GetLogs(c, level)
}

lines := strings.Split(out.String(), "\n")

return lines, nil
return lines
}

func (s *ServerService) GetConfigJson() (interface{}, error) {
Expand Down

0 comments on commit bf97191

Please sign in to comment.