Compare commits

...

4 Commits

Author SHA1 Message Date
github-actions[bot]
f5bc3c308a update contributors[no ci] 2025-01-19 21:46:26 +08:00
naiba
5ab4784acb feat: add nezha-ascii 2025-01-19 21:46:03 +08:00
仓鼠
c12fd2a7bf
feat: new theme nezha-ascii (#960)
* feat: new theme nezha-ascii

* chore: not audited

* chore: default

---------

Co-authored-by: naiba <hi@nai.ba>
2025-01-19 21:39:13 +08:00
UUBulb
4b1af369e3
small improvements (#958)
* small improvements

* fix: return empty iterator if no json present

* use time.Tick

* changes
2025-01-19 21:22:00 +08:00
12 changed files with 43 additions and 38 deletions

View File

@ -68,6 +68,7 @@ add your theme to [service/singleton/frontend-templates.yaml](service/singleton/
<a href="https://github.com/Mmx233" title="Mmx"><img src="https://avatars.githubusercontent.com/u/36563672?v=4" width="50;" alt="Mmx"/></a>
<a href="https://github.com/rootmelo92118" title="rootmelo92118"><img src="https://avatars.githubusercontent.com/u/32770959?v=4" width="50;" alt="rootmelo92118"/></a>
<a href="https://github.com/Moraxyc" title="Moraxyc"><img src="https://avatars.githubusercontent.com/u/69713071?v=4" width="50;" alt="Moraxyc"/></a>
<a href="https://github.com/hamster1963" title="仓鼠"><img src="https://avatars.githubusercontent.com/u/71394853?v=4" width="50;" alt="仓鼠"/></a>
<a href="https://github.com/zhucaidan" title="zhucaidan"><img src="https://avatars.githubusercontent.com/u/47970938?v=4" width="50;" alt="zhucaidan"/></a>
<a href="https://github.com/iilemon" title="Sean"><img src="https://avatars.githubusercontent.com/u/33201711?v=4" width="50;" alt="Sean"/></a>
<a href="https://github.com/lyj0309" title="lyj"><img src="https://avatars.githubusercontent.com/u/50474995?v=4" width="50;" alt="lyj"/></a>
@ -77,6 +78,7 @@ add your theme to [service/singleton/frontend-templates.yaml](service/singleton/
<a href="https://github.com/DarcJC" title="Darc Z."><img src="https://avatars.githubusercontent.com/u/53445798?v=4" width="50;" alt="Darc Z."/></a>
<a href="https://github.com/Creling" title="Creling"><img src="https://avatars.githubusercontent.com/u/43109504?v=4" width="50;" alt="Creling"/></a>
<a href="https://github.com/coreff" title="Core F"><img src="https://avatars.githubusercontent.com/u/38347122?v=4" width="50;" alt="Core F"/></a>
<a href="https://github.com/adminsama" title="adminsama"><img src="https://avatars.githubusercontent.com/u/60880076?v=4" width="50;" alt="adminsama"/></a>
<a href="https://github.com/acgpiano" title="Acgpiano"><img src="https://avatars.githubusercontent.com/u/15900800?v=4" width="50;" alt="Acgpiano"/></a>
<a href="https://github.com/eya46" title="eya46"><img src="https://avatars.githubusercontent.com/u/61458340?v=4" width="50;" alt="eya46"/></a>
<a href="https://github.com/guoyongchang" title="guoyongchang"><img src="https://avatars.githubusercontent.com/u/10484506?v=4" width="50;" alt="guoyongchang"/></a>
@ -88,11 +90,9 @@ add your theme to [service/singleton/frontend-templates.yaml](service/singleton/
<a href="https://github.com/unclezs" title="unclezs"><img src="https://avatars.githubusercontent.com/u/42318775?v=4" width="50;" alt="unclezs"/></a>
<a href="https://github.com/ysicing" title="缘生"><img src="https://avatars.githubusercontent.com/u/8605565?v=4" width="50;" alt="缘生"/></a>
<a href="https://github.com/yanhao98" title="严浩"><img src="https://avatars.githubusercontent.com/u/37316281?v=4" width="50;" alt="严浩"/></a>
<a href="https://github.com/hamster1963" title="仓鼠"><img src="https://avatars.githubusercontent.com/u/71394853?v=4" width="50;" alt="仓鼠"/></a>
<a href="https://github.com/arkylin" title="凌"><img src="https://avatars.githubusercontent.com/u/35104502?v=4" width="50;" alt="凌"/></a>
<a href="https://github.com/yumusb" title="榆木"><img src="https://avatars.githubusercontent.com/u/43062104?v=4" width="50;" alt="榆木"/></a>
<a href="https://github.com/colour93" title="玖叁"><img src="https://avatars.githubusercontent.com/u/64313711?v=4" width="50;" alt="玖叁"/></a>
<a href="https://github.com/adminsama" title="adminsama"><img src="https://avatars.githubusercontent.com/u/60880076?v=4" width="50;" alt="adminsama"/></a>
<a href="https://github.com/hmsjy2017" title="Tony"><img src="https://avatars.githubusercontent.com/u/42692274?v=4" width="50;" alt="Tony"/></a>
<a href="https://github.com/nickfox-taterli" title="Tater Li"><img src="https://avatars.githubusercontent.com/u/19658596?v=4" width="50;" alt="Tater Li"/></a>
<a href="https://github.com/IamTaoChen" title="Tao Chen"><img src="https://avatars.githubusercontent.com/u/42793494?v=4" width="50;" alt="Tao Chen"/></a>

View File

@ -102,7 +102,7 @@ func (r *AlertRule) Check(points [][]bool) (maxDuration int, passed bool) {
hasPassedRule = true
continue
}
total, fail := 0.0, 0.0
total, fail := 0, 0
for timeTick := len(points) - duration; timeTick < len(points); timeTick++ {
total++
if !points[timeTick][ruleId] {
@ -110,7 +110,7 @@ func (r *AlertRule) Check(points [][]bool) (maxDuration int, passed bool) {
}
}
// 当70%以上的采样点未通过规则判断时 才认为当前检查未通过
if fail/total <= 0.7 {
if fail*100/total <= 70 {
hasPassedRule = true
}
}

View File

@ -70,7 +70,7 @@ func (ns *NotificationServerBundle) reqBody(message string) (string, error) {
return string(msgBytes)[1 : len(msgBytes)-1]
}), nil
case NotificationRequestTypeForm:
data, err := utils.GjsonParseStringMap(n.RequestBody)
data, err := utils.GjsonIter(n.RequestBody)
if err != nil {
return "", err
}
@ -98,7 +98,7 @@ func (n *Notification) setRequestHeader(req *http.Request) error {
if n.RequestHeader == "" {
return nil
}
m, err := utils.GjsonParseStringMap(n.RequestHeader)
m, err := utils.GjsonIter(n.RequestHeader)
if err != nil {
return err
}

View File

@ -48,11 +48,11 @@ func (provider *Provider) UpdateDomain(ctx context.Context) {
for _, domain := range provider.DDNSProfile.Domains {
for retries := 0; retries < int(provider.DDNSProfile.MaxRetries); retries++ {
provider.domain = domain
log.Printf("NEZHA>> 正在尝试更新域名(%s)DDNS(%d/%d)", provider.domain, retries+1, provider.DDNSProfile.MaxRetries)
log.Printf("NEZHA>> Updating DNS Record of domain %s: %d/%d", provider.domain, retries+1, provider.DDNSProfile.MaxRetries)
if err := provider.updateDomain(); err != nil {
log.Printf("NEZHA>> 尝试更新域名(%s)DDNS失败: %v", provider.domain, err)
log.Printf("NEZHA>> Failed to update DNS record of domain %s: %v", provider.domain, err)
} else {
log.Printf("NEZHA>> 尝试更新域名(%s)DDNS成功", provider.domain)
log.Printf("NEZHA>> Update DNS record of domain %s succeed", provider.domain)
break
}
}

View File

@ -77,7 +77,7 @@ func (provider *Provider) prepareRequest(ctx context.Context) (*http.Request, er
return nil, err
}
headers, err := utils.GjsonParseStringMap(
headers, err := utils.GjsonIter(
provider.formatWebhookString(provider.DDNSProfile.WebhookHeaders))
if err != nil {
return nil, err
@ -139,7 +139,7 @@ func (provider *Provider) reqBody() (string, error) {
case requestTypeJSON:
return provider.formatWebhookString(provider.DDNSProfile.WebhookRequestBody), nil
case requestTypeForm:
data, err := utils.GjsonParseStringMap(provider.DDNSProfile.WebhookRequestBody)
data, err := utils.GjsonIter(provider.DDNSProfile.WebhookRequestBody)
if err != nil {
return "", err
}

View File

@ -2,6 +2,7 @@ package utils
import (
"errors"
"iter"
"github.com/tidwall/gjson"
)
@ -11,6 +12,8 @@ var (
ErrGjsonWrongType = errors.New("wrong type")
)
var emptyIterator = func(yield func(string, string) bool) {}
func GjsonGet(json []byte, path string) (gjson.Result, error) {
result := gjson.GetBytes(json, path)
if !result.Exists() {
@ -20,21 +23,19 @@ func GjsonGet(json []byte, path string) (gjson.Result, error) {
return result, nil
}
func GjsonParseStringMap(jsonObject string) (map[string]string, error) {
if jsonObject == "" {
return nil, nil
func GjsonIter(json string) (iter.Seq2[string, string], error) {
if json == "" {
return emptyIterator, nil
}
result := gjson.Parse(jsonObject)
result := gjson.Parse(json)
if !result.IsObject() {
return nil, ErrGjsonWrongType
}
ret := make(map[string]string)
result.ForEach(func(key, value gjson.Result) bool {
ret[key.String()] = value.String()
return true
})
return ret, nil
return func(yield func(string, string) bool) {
result.ForEach(func(k, v gjson.Result) bool {
return yield(k.String(), v.String())
})
}, nil
}

View File

@ -239,7 +239,7 @@ func (s *NezhaHandler) ReportGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, e
}(provider)
}
} else {
log.Printf("NEZHA>> 获取DDNS配置时发生错误: %v", err)
log.Printf("NEZHA>> Failed to retrieve DDNS configuration: %v", err)
}
}

View File

@ -74,20 +74,19 @@ func AlertSentinelStart() {
AlertsLock.Unlock()
time.Sleep(time.Second * 10)
var lastPrint time.Time
lastPrint := time.Now()
var checkCount uint64
for {
startedAt := time.Now()
ticker := time.Tick(3 * time.Second) // 3秒钟检查一次
for startedAt := range ticker {
checkStatus()
checkCount++
if lastPrint.Before(startedAt.Add(-1 * time.Hour)) {
if Conf.Debug {
log.Println("NEZHA>> 报警规则检测每小时", checkCount, "次", startedAt, time.Now())
log.Printf("NEZHA>> Checking alert rules %d times each hour %v %v", checkCount, startedAt, time.Now())
}
checkCount = 0
lastPrint = startedAt
}
time.Sleep(time.Until(startedAt.Add(time.Second * 3))) // 3秒钟检查一次
}
}

View File

@ -2,15 +2,20 @@
name: "OfficialAdmin"
repository: "https://github.com/nezhahq/admin-frontend"
author: "nezhahq"
version: "v1.5.12"
version: "v1.5.13"
isadmin: true
isofficial: true
- path: "user-dist"
name: "Official"
repository: "https://github.com/hamster1963/nezha-dash-v1"
author: "hamster1963"
version: "v1.12.5"
version: "v1.13.0"
isofficial: true
- path: "nezha-ascii-dist"
name: "Nezha-ASCII"
repository: "https://github.com/hamster1963/nezha-ascii"
author: "hamster1963"
version: "v1.0.0"
- path: "nazhua-dist"
name: "Nazhua"
repository: "https://github.com/hi2shark/nazhua"

View File

@ -247,7 +247,7 @@ func SendNotification(notificationGroupID uint64, desc string, muteLabel *string
if !flag {
if Conf.Debug {
log.Println("NEZHA>> 静音的重复通知:", desc, muteLabel)
log.Println("NEZHA>> Muted repeated notification", desc, muteLabel)
}
return
}
@ -256,7 +256,7 @@ func SendNotification(notificationGroupID uint64, desc string, muteLabel *string
NotificationsLock.RLock()
defer NotificationsLock.RUnlock()
for _, n := range NotificationList[notificationGroupID] {
log.Println("NEZHA>> 尝试通知", n.Name)
log.Printf("NEZHA>> Try to notify %s", n.Name)
}
for _, n := range NotificationList[notificationGroupID] {
ns := model.NotificationServerBundle{
@ -268,9 +268,9 @@ func SendNotification(notificationGroupID uint64, desc string, muteLabel *string
ns.Server = ext[0]
}
if err := ns.Send(desc); err != nil {
log.Println("NEZHA>> 向 ", n.Name, " 发送通知失败:", err)
log.Printf("NEZHA>> Sending notification to %s failed: %v", n.Name, err)
} else {
log.Println("NEZHA>> 向 ", n.Name, " 发送通知成功:")
log.Printf("NEZHA>> Sending notification to %s succeed", n.Name)
}
}
}

View File

@ -359,7 +359,7 @@ func (ss *ServiceSentinel) worker() {
// 从服务状态汇报管道获取汇报的服务数据
for r := range ss.serviceReportChannel {
if ss.Services[r.Data.GetId()] == nil || ss.Services[r.Data.GetId()].ID == 0 {
log.Printf("NEZHA>> 错误的服务监控上报 %+v", r)
log.Printf("NEZHA>> Incorrect service monitor report %+v", r)
continue
}
mh := r.Data
@ -383,7 +383,7 @@ func (ss *ServiceSentinel) worker() {
Data: mh.Data,
ServerID: r.Reporter,
}).Error; err != nil {
log.Println("NEZHA>> 服务监控数据持久化失败:", err)
log.Printf("NEZHA>> Failed to save service monitor metrics: %v", err)
}
}
serviceTcpMap[r.Reporter] = ts
@ -450,7 +450,7 @@ func (ss *ServiceSentinel) worker() {
Up: ss.serviceResponseDataStoreCurrentUp[mh.GetId()],
Down: ss.serviceResponseDataStoreCurrentDown[mh.GetId()],
}).Error; err != nil {
log.Println("NEZHA>> 服务监控数据持久化失败:", err)
log.Printf("NEZHA>> Failed to save service monitor metrics: %v", err)
}
}

View File

@ -112,7 +112,7 @@ func RecordTransferHourlyUsage() {
if len(txs) == 0 {
return
}
log.Println("NEZHA>> Cron 流量统计入库", len(txs), DB.Create(txs).Error)
log.Printf("NEZHA>> Saved traffic metrics to database. Affected %d row(s), Error: %v", len(txs), DB.Create(txs).Error)
}
// CleanServiceHistory 清理无效或过时的 监控记录 和 流量记录