重新整理物联网服务,分离业务逻辑。
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,15 +12,15 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
banner := `
|
banner := `
|
||||||
==========================================================================
|
==========================================================================
|
||||||
_______ _______ _ __________________ _ _______ _
|
|
||||||
( ____ \( ____ \( ( /|\__ __/\__ __/( ( /|( ____ \( \
|
██████ █████ █████ ██████ ██ █████ ██████ ██ ██ ██████
|
||||||
| (_____ | (__ | \ | | | | | | | \ | || (__ | |
|
██ ██ ██ ██ ██ ████ ██ ██ ███ ██ ██
|
||||||
(_____ )| __) | (\ \) | | | | | | (\ \) || __) | |
|
█████ ██ ██ ██ ██ █████ ██ ██ ██ ██ █████ ████ ██ ██
|
||||||
/\____) || (____/\| ) \ | | | ___) (___| ) \ || (____/\| (____/\
|
██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██ ████ ██
|
||||||
\_______)(_______/|/ )_) )_( \_______/|/ )_)(_______/(_______/
|
██████ █████ █████ ██████ ██ ██ █████ ██████ ██ ██ ██
|
||||||
|
|
||||||
==========================================================================
|
==========================================================================
|
||||||
`
|
`
|
||||||
|
|
||||||
fmt.Println(banner)
|
fmt.Println(banner)
|
||||||
deviceID := device.GetDeviceID()
|
deviceID := device.GetDeviceID()
|
||||||
log.Init(config.Log_file_dic) // 初始化日志目录
|
log.Init(config.Log_file_dic) // 初始化日志目录
|
||||||
@@ -54,8 +54,6 @@ func main() {
|
|||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// 个人业务
|
|
||||||
test()
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7,6 +7,8 @@ const (
|
|||||||
// 版本号
|
// 版本号
|
||||||
APP_VERSION = 1
|
APP_VERSION = 1
|
||||||
|
|
||||||
|
BASE_URL = "https://ai.ronsunny.cn:8090"
|
||||||
|
//BASE_URL = "http://127.0.0.1:13011"
|
||||||
Log_file_dic = "./logs"
|
Log_file_dic = "./logs"
|
||||||
MQTT_BROKER = "tls://ai.ronsunny.cn:8093"
|
MQTT_BROKER = "tls://ai.ronsunny.cn:8093"
|
||||||
PASSWORD = "123456"
|
PASSWORD = "123456"
|
||||||
@@ -4,7 +4,6 @@ import "sentinel/pkg/model"
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
updateCheckURL = "/iot/common/update/check"
|
updateCheckURL = "/iot/common/update/check"
|
||||||
analyticsURL = "/api/public/sentinel-record-analytics"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckUpdate(deviceID string) (*model.UpdateInfo, error) {
|
func CheckUpdate(deviceID string) (*model.UpdateInfo, error) {
|
||||||
@@ -21,7 +20,3 @@ func CheckUpdate(deviceID string) (*model.UpdateInfo, error) {
|
|||||||
}
|
}
|
||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Analytics(req model.Record) error {
|
|
||||||
return Post(analyticsURL, req, nil)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"sentinel/pkg/model"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"sentinel/pkg/config"
|
||||||
|
"sentinel/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var client = &http.Client{
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get(path string, query map[string]string, out any) error {
|
||||||
|
return do(http.MethodGet, path, query, nil, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Post(path string, body any, out any) error {
|
||||||
|
return do(http.MethodPost, path, nil, body, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func do(method, path string, query map[string]string, body any, out any) error {
|
||||||
|
u, err := url.Parse(config.BASE_URL + path)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("parse url failed: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(query) > 0 {
|
||||||
|
q := u.Query()
|
||||||
|
for k, v := range query {
|
||||||
|
q.Set(k, v)
|
||||||
|
}
|
||||||
|
u.RawQuery = q.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqBody *bytes.Reader
|
||||||
|
if body != nil {
|
||||||
|
b, err := json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("marshal body failed: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reqBody = bytes.NewReader(b)
|
||||||
|
} else {
|
||||||
|
reqBody = bytes.NewReader(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(method, u.String(), reqBody)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("create request failed: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("apikey", "NzusyzcLIUoZ22tflHN2sOjHrry3W7zJ")
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("request failed: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||||
|
log.Error("http status error: " + resp.Status)
|
||||||
|
return fmt.Errorf("http status %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析成 BaseResponse
|
||||||
|
var baseResp model.BaseResponse
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&baseResp); err != nil {
|
||||||
|
log.Error("decode base response failed: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !baseResp.Status {
|
||||||
|
log.Error("server returned error: " + baseResp.Message)
|
||||||
|
return fmt.Errorf(baseResp.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
if out != nil && baseResp.Data != nil {
|
||||||
|
// 将 Data 转成业务类型
|
||||||
|
b, err := json.Marshal(baseResp.Data)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("marshal data failed: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(b, out); err != nil {
|
||||||
|
log.Error("unmarshal data to out failed: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Generated
+10
@@ -0,0 +1,10 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Ignored default folder with query files
|
||||||
|
/queries/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="project">
|
||||||
|
<words>
|
||||||
|
<w>linux</w>
|
||||||
|
<w>从海康sdk获取图片以及信息</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
Generated
+11
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GoImports">
|
||||||
|
<option name="excludedPackages">
|
||||||
|
<array>
|
||||||
|
<option value="github.com/pkg/errors" />
|
||||||
|
<option value="golang.org/x/net/context" />
|
||||||
|
</array>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/sentinel.iml" filepath="$PROJECT_DIR$/.idea/sentinel.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RemoteTargetsManager">
|
||||||
|
<targets>
|
||||||
|
<target name="WSL - Ubuntu-22.04" type="wsl" uuid="43159dba-0a6e-45fb-8b38-8e1c2ac28efa">
|
||||||
|
<config>
|
||||||
|
<option name="distributionMsId" value="Ubuntu-22.04" />
|
||||||
|
<option name="projectRootOnTarget" value="{exitCode=0, timeout=false, cancelled=false, stdout=/tmp/tmp.dVq8EjO5tG , stderr=}/Sentinel" />
|
||||||
|
</config>
|
||||||
|
<ContributedStateBase type="GoLanguageRuntime">
|
||||||
|
<config />
|
||||||
|
</ContributedStateBase>
|
||||||
|
</target>
|
||||||
|
</targets>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+15
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true">
|
||||||
|
<buildTags>
|
||||||
|
<option name="os" value="linux" />
|
||||||
|
<option name="arch" value="arm64" />
|
||||||
|
<option name="cgo" value="NO" />
|
||||||
|
</buildTags>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# ==========================
|
||||||
|
# Stage 1: Build the Go binary
|
||||||
|
# ==========================
|
||||||
|
FROM golang:1.21-alpine AS builder
|
||||||
|
|
||||||
|
# 设置工作目录
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
# 复制 go.mod 和 go.sum,先做依赖缓存
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
|
# 下载依赖(缓存层)
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
# 复制源代码
|
||||||
|
COPY app/ ./app
|
||||||
|
|
||||||
|
# 编译可执行文件
|
||||||
|
RUN go build -o sentinel ./app/main.go
|
||||||
|
|
||||||
|
# ==========================
|
||||||
|
# Stage 2: 生成最终运行镜像
|
||||||
|
# ==========================
|
||||||
|
FROM alpine:3.18
|
||||||
|
|
||||||
|
# 安装 ca-certificates,如果程序需要访问 HTTPS
|
||||||
|
RUN apk add --no-cache ca-certificates
|
||||||
|
|
||||||
|
# 设置工作目录
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制从 builder 构建好的二进制
|
||||||
|
COPY --from=builder /build/sentinel .
|
||||||
|
|
||||||
|
# 设置默认执行命令
|
||||||
|
CMD ["./sentinel"]
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logDir = "./logs" // 日志目录,可根据需要修改
|
||||||
|
|
||||||
|
// 初始化日志目录
|
||||||
|
func Init() {
|
||||||
|
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||||||
|
fmt.Println("create log dir failed:", err)
|
||||||
|
}
|
||||||
|
cleanupOldLogs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup 删除超过7天的日志文件
|
||||||
|
func cleanupOldLogs() {
|
||||||
|
files, err := os.ReadDir(logDir)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cutoff := time.Now().AddDate(0, 0, -7)
|
||||||
|
for _, f := range files {
|
||||||
|
if f.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
info, err := f.Info()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if info.ModTime().Before(cutoff) {
|
||||||
|
_ = os.Remove(filepath.Join(logDir, f.Name()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// log 内部写文件
|
||||||
|
func logToFile(level, msg string) {
|
||||||
|
fmt.Println(msg)
|
||||||
|
t := time.Now()
|
||||||
|
// 确保日志目录存在
|
||||||
|
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||||||
|
fmt.Println("create log dir failed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := filepath.Join(logDir, t.Format("2006-01-02")+".log")
|
||||||
|
f, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("open log file failed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
line := fmt.Sprintf("%s [%s] %s\n", t.Format("2006-01-02 15:04:05"), level, msg)
|
||||||
|
_, _ = f.WriteString(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对外接口
|
||||||
|
func Info(msg string) {
|
||||||
|
logToFile("INFO", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Println 支持多个参数拼接,写 INFO 日志
|
||||||
|
func Println(v ...interface{}) {
|
||||||
|
msg := fmt.Sprint(v...)
|
||||||
|
logToFile("INFO", msg)
|
||||||
|
}
|
||||||
|
func Warn(msg string) {
|
||||||
|
logToFile("WARN", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error(msg string) {
|
||||||
|
logToFile("ERROR", msg)
|
||||||
|
}
|
||||||
|
func Fatal(err error) {
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logToFile("ERROR", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatal 打印错误日志并退出程序
|
||||||
|
func Fatalf(msg string, args ...interface{}) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
msg = fmt.Sprintf(msg, args...)
|
||||||
|
}
|
||||||
|
logToFile("FATAL", msg)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
@@ -3,25 +3,38 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sentinel/pkg/device"
|
"sentinel/app/log"
|
||||||
"sentinel/pkg/log"
|
"sentinel/app/model"
|
||||||
"sentinel/pkg/model"
|
"sentinel/app/net"
|
||||||
api "sentinel/pkg/net"
|
"sentinel/app/storage"
|
||||||
"sentinel/pkg/storage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func test() {
|
func main() {
|
||||||
|
banner := `
|
||||||
|
==========================================================================
|
||||||
|
_______ _______ _ __________________ _ _______ _
|
||||||
|
( ____ \( ____ \( ( /|\__ __/\__ __/( ( /|( ____ \( \
|
||||||
|
| (_____ | (__ | \ | | | | | | | \ | || (__ | |
|
||||||
|
(_____ )| __) | (\ \) | | | | | | (\ \) || __) | |
|
||||||
|
/\____) || (____/\| ) \ | | | ___) (___| ) \ || (____/\| (____/\
|
||||||
|
\_______)(_______/|/ )_) )_( \_______/|/ )_)(_______/(_______/
|
||||||
|
==========================================================================
|
||||||
|
`
|
||||||
|
deviceID := "6823316af0e540bea818ec1be25cc14a"
|
||||||
|
log.Init() // 初始化日志目录
|
||||||
|
log.Info("Device id: " + deviceID) // 第一次启动记录
|
||||||
|
log.Info(banner)
|
||||||
// 0. 从海康SDK获取图片以及信息
|
// 0. 从海康SDK获取图片以及信息
|
||||||
record := loadData()
|
record := loadData(deviceID)
|
||||||
// 1. 上传图片到OSS
|
// 1. 上传图片到OSS
|
||||||
uploadFile(record.LicensePlateImage, record.VehicleImage)
|
uploadFile(record.LicensePlateImage, record.VehicleImage)
|
||||||
// 2. 调用分析请求
|
// 2. 调用分析请求
|
||||||
analytics(record)
|
analytics(record)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadData() model.Record {
|
func loadData(deviceID string) model.Record {
|
||||||
return model.Record{
|
return model.Record{
|
||||||
DeviceId: device.GetDeviceID(),
|
DeviceId: deviceID, //从环境变量取
|
||||||
LicensePlate: "晋A-888888",
|
LicensePlate: "晋A-888888",
|
||||||
LicensePlateImage: "licensePlateImage_test1.jpg",
|
LicensePlateImage: "licensePlateImage_test1.jpg",
|
||||||
VehicleType: "大型货车",
|
VehicleType: "大型货车",
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type BaseResponse struct {
|
||||||
|
Status bool `json:"status"` // 是否成功
|
||||||
|
Message string `json:"message"` // 提示信息
|
||||||
|
Data interface{} `json:"data,omitempty"` // 泛型数据,用 interface{} 接收任意类型
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sentinel/app/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
analyticsURL = "/api/public/sentinel-record-analytics"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Analytics(req model.Record) error {
|
||||||
|
return Post(analyticsURL, req, nil)
|
||||||
|
}
|
||||||
@@ -6,10 +6,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sentinel/pkg/model"
|
"sentinel/app/log"
|
||||||
|
"sentinel/app/model"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"sentinel/pkg/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// const baseURL = "http://127.0.0.1:13011"
|
// const baseURL = "http://127.0.0.1:13011"
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/v3/cpu"
|
||||||
|
"github.com/shirou/gopsutil/v3/disk"
|
||||||
|
"github.com/shirou/gopsutil/v3/mem"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetLocalIP() string {
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if iface.Flags&net.FlagUp == 0 {
|
||||||
|
continue // 接口未启用
|
||||||
|
}
|
||||||
|
if iface.Flags&net.FlagLoopback != 0 {
|
||||||
|
continue // 忽略回环
|
||||||
|
}
|
||||||
|
addrs, err := iface.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
}
|
||||||
|
if ip == nil || ip.IsLoopback() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ip = ip.To4()
|
||||||
|
if ip == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return ip.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetHostname() string {
|
||||||
|
name, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
func GetMacAddress() string {
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mac := iface.HardwareAddr.String()
|
||||||
|
if mac != "" {
|
||||||
|
return mac
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOSInfo() string {
|
||||||
|
return runtime.GOOS // windows, linux, darwin
|
||||||
|
}
|
||||||
|
func GetCPUInfo() string {
|
||||||
|
info, err := cpu.Info()
|
||||||
|
if err != nil || len(info) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return info[0].ModelName
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMemory() string {
|
||||||
|
v, err := mem.VirtualMemory()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%dMB", v.Total/1024/1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDisk() string {
|
||||||
|
usage, err := disk.Usage("/")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%dGB", usage.Total/1024/1024/1024)
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
module sentinel
|
||||||
|
|
||||||
|
go 1.25.5
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/eclipse/paho.mqtt.golang v1.5.1 // indirect
|
||||||
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||||
|
github.com/klauspost/crc32 v1.3.0 // indirect
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||||
|
github.com/minio/crc64nvme v1.1.0 // indirect
|
||||||
|
github.com/minio/md5-simd v1.1.2 // indirect
|
||||||
|
github.com/minio/minio-go/v7 v7.0.97 // indirect
|
||||||
|
github.com/philhofer/fwd v1.2.0 // indirect
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||||
|
github.com/rs/xid v1.6.0 // indirect
|
||||||
|
github.com/shirou/gopsutil/v3 v3.24.5 // indirect
|
||||||
|
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||||
|
github.com/tinylib/msgp v1.3.0 // indirect
|
||||||
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
|
golang.org/x/crypto v0.42.0 // indirect
|
||||||
|
golang.org/x/net v0.44.0 // indirect
|
||||||
|
golang.org/x/sync v0.17.0 // indirect
|
||||||
|
golang.org/x/sys v0.36.0 // indirect
|
||||||
|
golang.org/x/text v0.29.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
|
github.com/eclipse/paho.mqtt.golang v1.5.1 h1:/VSOv3oDLlpqR2Epjn1Q7b2bSTplJIeV2ISgCl2W7nE=
|
||||||
|
github.com/eclipse/paho.mqtt.golang v1.5.1/go.mod h1:1/yJCneuyOoCOzKSsOTUc0AJfpsItBGWvYpBLimhArU=
|
||||||
|
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||||
|
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
|
github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM=
|
||||||
|
github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw=
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
|
github.com/minio/crc64nvme v1.1.0 h1:e/tAguZ+4cw32D+IO/8GSf5UVr9y+3eJcxZI2WOO/7Q=
|
||||||
|
github.com/minio/crc64nvme v1.1.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||||
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
|
github.com/minio/minio-go/v7 v7.0.97 h1:lqhREPyfgHTB/ciX8k2r8k0D93WaFqxbJX36UZq5occ=
|
||||||
|
github.com/minio/minio-go/v7 v7.0.97/go.mod h1:re5VXuo0pwEtoNLsNuSr0RrLfT/MBtohwdaSmPPSRSk=
|
||||||
|
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||||
|
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||||
|
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||||
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
|
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
|
||||||
|
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
|
||||||
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
|
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||||
|
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
|
||||||
|
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||||
|
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||||
|
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||||
|
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||||
|
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
|
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||||
|
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||||
|
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||||
|
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||||
|
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||||
|
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||||
|
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||||
|
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
Reference in New Issue
Block a user