[agent-wdd] 完成自定义log部分;完成info network部分; 项目结构基本完成
This commit is contained in:
42
agent-wdd/agent-wdd-config.yaml
Normal file
42
agent-wdd/agent-wdd-config.yaml
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
timestamp: 2025-02-10 15:19:30
|
||||
|
||||
agent:
|
||||
hostname: Shanghai-amd64-01
|
||||
network:
|
||||
# 2代表能上外网 1代表能上国内网 0代表无法访问网络
|
||||
internet: 2
|
||||
# 服务器公网信息
|
||||
public:
|
||||
ipv4: 42.192.52.227
|
||||
ipv6: xxx
|
||||
country: CN
|
||||
city: Shanghai
|
||||
asn: Oracle
|
||||
interfaces:
|
||||
- name: eth0
|
||||
ipv4: 192.168.233.5
|
||||
mac: asdasdasd
|
||||
cpu:
|
||||
cores: 4
|
||||
brand: Intel Xeon Gold 5118
|
||||
mhz: 2400
|
||||
mem:
|
||||
size: 4G
|
||||
type: ddr4
|
||||
speed: 2400
|
||||
swap:
|
||||
on: false
|
||||
size: 2G
|
||||
disk:
|
||||
- path: /
|
||||
size: 50G
|
||||
usage: 12G
|
||||
percent: 12/50
|
||||
vg: ubuntuvg
|
||||
lv: datalv
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
20
agent-wdd/cmd/Info.go
Normal file
20
agent-wdd/cmd/Info.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"agent-wdd/config"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func addInfoSubcommands(cmd *cobra.Command) {
|
||||
// network
|
||||
network := &cobra.Command{
|
||||
Use: "network",
|
||||
Short: "主机Network相关的信息",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
network := config.ConfigCache.Agent.Network
|
||||
network.Gather()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(network)
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"agent-wdd/config"
|
||||
"agent-wdd/log"
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"os"
|
||||
)
|
||||
|
||||
const WddConfigFilePath = "/usr/local/etc/wdd/"
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "wdd",
|
||||
Short: "wdd应用程序是wdd封装的NB工具",
|
||||
@@ -23,7 +22,7 @@ var projectBase = ""
|
||||
|
||||
func init() {
|
||||
|
||||
cobra.OnInitialize(initConfig)
|
||||
cobra.OnInitialize(config.InitConfig)
|
||||
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
|
||||
rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "",
|
||||
@@ -38,24 +37,6 @@ func init() {
|
||||
viper.SetDefault("license", "apache")
|
||||
}
|
||||
|
||||
func initConfig() {
|
||||
// Don't forget to read config either from cfgFile or from home directory!
|
||||
if cfgFile != "" {
|
||||
// Use config file from the flag.
|
||||
viper.SetConfigFile(cfgFile)
|
||||
} else {
|
||||
|
||||
// Search config in home directory with name ".cobra" (without extension).
|
||||
viper.AddConfigPath(WddConfigFilePath)
|
||||
viper.SetConfigName(".cobra")
|
||||
}
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
fmt.Println("Can't read config:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
|
||||
// 1. base命令
|
||||
@@ -103,10 +84,8 @@ func Execute() {
|
||||
infoCmd := &cobra.Command{
|
||||
Use: "info",
|
||||
Short: "打印主机详细信息",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// 实现info逻辑
|
||||
},
|
||||
}
|
||||
addInfoSubcommands(infoCmd)
|
||||
|
||||
// 8. version命令
|
||||
versionCmd := &cobra.Command{
|
||||
@@ -114,6 +93,10 @@ func Execute() {
|
||||
Short: "打印版本信息",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// 实现version逻辑
|
||||
log.Debug("来自王达达的礼物 !")
|
||||
log.Info("来自王达达的礼物 !")
|
||||
log.Warning("来自王达达的礼物 !")
|
||||
log.Error("来自王达达的礼物 !")
|
||||
},
|
||||
}
|
||||
|
||||
@@ -149,8 +132,4 @@ func Execute() {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
120
agent-wdd/config/Config.go
Normal file
120
agent-wdd/config/Config.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"agent-wdd/log"
|
||||
"agent-wdd/utils"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v3"
|
||||
"os"
|
||||
)
|
||||
|
||||
var WddConfigFilePath = "/usr/local/etc/wdd/agent-wdd-config.yaml"
|
||||
|
||||
var ConfigCache *Config
|
||||
|
||||
func init() {
|
||||
// 根据运行的操作系统不同, 修改 WddConfigFilePath 的位置
|
||||
}
|
||||
|
||||
// 配置结构体定义
|
||||
type Config struct {
|
||||
TimeStamp string `yaml:"timestamp"`
|
||||
Agent Agent `yaml:"agent"`
|
||||
}
|
||||
|
||||
type Agent struct {
|
||||
Hostname string `yaml:"hostname"`
|
||||
Network Network `yaml:"network"`
|
||||
CPU CPU `yaml:"cpu"`
|
||||
Mem Memory `yaml:"mem"`
|
||||
Swap Swap `yaml:"swap"`
|
||||
Disk []Disk `yaml:"disk"`
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
Internet int `yaml:"internet"`
|
||||
Public PublicInfo `yaml:"public"`
|
||||
Interfaces []Interface `yaml:"interfaces"`
|
||||
}
|
||||
|
||||
type PublicInfo struct {
|
||||
IPv4 string `yaml:"ipv4"`
|
||||
IPv6 string `yaml:"ipv6"`
|
||||
Country string `yaml:"country"`
|
||||
City string `yaml:"city"`
|
||||
ASN string `yaml:"asn"`
|
||||
}
|
||||
|
||||
type Interface struct {
|
||||
Name string `yaml:"name"`
|
||||
IPv4 string `yaml:"ipv4"`
|
||||
IPv6 string `yaml:"ipv6"`
|
||||
MAC string `yaml:"mac"`
|
||||
}
|
||||
|
||||
type CPU struct {
|
||||
Cores int `yaml:"cores"`
|
||||
Brand string `yaml:"brand"`
|
||||
Mhz int `yaml:"mhz"`
|
||||
}
|
||||
|
||||
type Memory struct {
|
||||
Size string `yaml:"size"`
|
||||
Type string `yaml:"type"`
|
||||
Speed int `yaml:"speed"`
|
||||
}
|
||||
|
||||
type Swap struct {
|
||||
On bool `yaml:"on"`
|
||||
Size string `yaml:"size"`
|
||||
}
|
||||
|
||||
type Disk struct {
|
||||
Path string `yaml:"path"`
|
||||
Size string `yaml:"size"`
|
||||
Usage string `yaml:"usage"`
|
||||
Percent string `yaml:"percent"`
|
||||
VG string `yaml:"vg"`
|
||||
LV string `yaml:"lv"`
|
||||
}
|
||||
|
||||
func InitConfig() {
|
||||
|
||||
// 检查配置文件是否存在
|
||||
if !utils.FileOrFolderExists(WddConfigFilePath) {
|
||||
utils.AppendContentToFile("", WddConfigFilePath)
|
||||
}
|
||||
|
||||
v := viper.New()
|
||||
v.SetConfigFile(WddConfigFilePath)
|
||||
v.SetConfigType("yaml")
|
||||
|
||||
if err := v.ReadInConfig(); err != nil {
|
||||
|
||||
log.Error("读取配置文件失败: %w", err)
|
||||
panic(err)
|
||||
|
||||
}
|
||||
|
||||
if err := v.Unmarshal(&ConfigCache); err != nil {
|
||||
log.Error("解析配置失败: %w", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 写入配置文件
|
||||
func SaveConfig() {
|
||||
|
||||
// 每次写入新的时间
|
||||
ConfigCache.TimeStamp = utils.CurrentTimeString()
|
||||
|
||||
data, err := yaml.Marshal(&ConfigCache)
|
||||
if err != nil {
|
||||
log.Error("YAML序列化失败: %w", err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(WddConfigFilePath, data, 0644); err != nil {
|
||||
log.Error("写入文件失败: %w", err)
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"net"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type AgentServerInfo struct {
|
||||
NetworkInfo
|
||||
CPUInfo
|
||||
}
|
||||
|
||||
type NetworkInfo struct {
|
||||
Interfaces []InterfaceInfo
|
||||
}
|
||||
|
||||
type InterfaceInfo struct {
|
||||
Name string
|
||||
HardwareAddr string
|
||||
Addrs []string
|
||||
}
|
||||
|
||||
func GetNetworkInfo() (*NetworkInfo, error) {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var networkInfo NetworkInfo
|
||||
for _, iface := range interfaces {
|
||||
var addrs []string
|
||||
addresses, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, addr := range addresses {
|
||||
addrs = append(addrs, addr.String())
|
||||
}
|
||||
|
||||
interfaceInfo := InterfaceInfo{
|
||||
Name: iface.Name,
|
||||
HardwareAddr: iface.HardwareAddr.String(),
|
||||
Addrs: addrs,
|
||||
}
|
||||
networkInfo.Interfaces = append(networkInfo.Interfaces, interfaceInfo)
|
||||
}
|
||||
|
||||
return &networkInfo, nil
|
||||
}
|
||||
|
||||
type CPUInfo struct {
|
||||
ModelName string
|
||||
Cores int
|
||||
Mhz float64
|
||||
}
|
||||
|
||||
func GetCpuInfo() CPUInfo {
|
||||
info := CPUInfo{}
|
||||
info.ModelName = runtime.GOARCH
|
||||
info.Cores = runtime.NumCPU()
|
||||
info.Mhz = 0.0
|
||||
return info
|
||||
}
|
||||
|
||||
func (info *AgentServerInfo) GetAgentInfo() {
|
||||
|
||||
}
|
||||
@@ -1,25 +1,149 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"agent-wdd/log"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CanConnectInternet 判定主机能否上网 请求 www.google.com 如果请求正常 返回2 如果超时三秒 请求baidu.com,如果没有错误返回1 如果错误返回0
|
||||
// 能够联网,就大于这个数字 外网9 国内7 不能联网1 未知0
|
||||
const InternetBaseLine = 1
|
||||
|
||||
// 定义响应数据结构体
|
||||
type IPInfo struct {
|
||||
IP string `json:"ip"`
|
||||
City string `json:"city"`
|
||||
Region string `json:"region"`
|
||||
Country string `json:"country"`
|
||||
Loc string `json:"loc"`
|
||||
Org string `json:"org"`
|
||||
Postal string `json:"postal"`
|
||||
Timezone string `json:"timezone"`
|
||||
}
|
||||
|
||||
// Gather 获取网络相关的信息
|
||||
func (network *Network) Gather() {
|
||||
// 能够联网
|
||||
network.Internet = CanConnectInternet()
|
||||
|
||||
// 获取公网的相关信息
|
||||
pub := PublicInfo{}
|
||||
pub.GetPublicInfo()
|
||||
|
||||
network.Public = pub
|
||||
|
||||
//获取本机网卡相关的内容
|
||||
}
|
||||
|
||||
// CanConnectInternet 判定主机能够上网
|
||||
func CanConnectInternet() int {
|
||||
// 读取 config 文件,判定能否上网
|
||||
internetCode := ConfigCache.Agent.Network.Internet
|
||||
|
||||
if internetCode == 0 {
|
||||
// 没有相关的信息,需要重新判定
|
||||
internetCode = judgeCanConnectInternet()
|
||||
|
||||
// 持久化保存
|
||||
ConfigCache.Agent.Network.Internet = internetCode
|
||||
SaveConfig()
|
||||
}
|
||||
|
||||
return internetCode
|
||||
}
|
||||
|
||||
// judgeCanConnectInternet 请求网址判定主机能否上网 请求 www.google.com 如果请求正常 返回9 如果超时三秒 请求baidu.com,如果没有错误返回7 如果错误返回1
|
||||
func judgeCanConnectInternet() int {
|
||||
client := http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
|
||||
_, err := client.Get("https://www.google.com")
|
||||
if err == nil {
|
||||
return 2
|
||||
return 9
|
||||
}
|
||||
|
||||
_, err = client.Get("https://www.baidu.com")
|
||||
if err == nil {
|
||||
return 1
|
||||
return 7
|
||||
}
|
||||
|
||||
return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
// GetPublicInfo 获取服务器的公网信息
|
||||
func (p PublicInfo) GetPublicInfo() {
|
||||
|
||||
if CanConnectInternet() == InternetBaseLine {
|
||||
// 无法联网, 假信息
|
||||
|
||||
fakePublicInfo := PublicInfo{
|
||||
IPv4: "1.1.1.1",
|
||||
IPv6: "2400::1",
|
||||
Country: "CN",
|
||||
City: "Shanghai",
|
||||
ASN: "Wdd Inc",
|
||||
}
|
||||
|
||||
ConfigCache.Agent.Network.Public = fakePublicInfo
|
||||
|
||||
SaveConfig()
|
||||
return
|
||||
}
|
||||
|
||||
// 可以联网
|
||||
// 创建带有超时的HTTP客户端
|
||||
client := &http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
|
||||
// 创建新的请求对象
|
||||
req, err := http.NewRequest("GET", "https://ipinfo.io", nil)
|
||||
if err != nil {
|
||||
log.Error("创建请求失败: %v", err)
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
req.Header.Add("Authorization", "Bearer 6ecb0db9bd8f19")
|
||||
req.Header.Add("Accept", "application/json")
|
||||
|
||||
// 发送请求
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Error("请求PublicInfo失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 检查响应状态码
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
log.Error("非200状态码: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Error("读取响应失败: %v", err)
|
||||
}
|
||||
|
||||
// 解析JSON数据
|
||||
var info IPInfo
|
||||
if err := json.Unmarshal(body, &info); err != nil {
|
||||
log.Error("JSON解析失败: %v", err)
|
||||
}
|
||||
|
||||
// 打印解析结果
|
||||
log.Info("IP信息:\n%+v\n", info)
|
||||
|
||||
// 保存信息
|
||||
p.IPv4 = info.IP
|
||||
p.ASN = info.Org
|
||||
p.Country = info.Country
|
||||
p.City = info.City
|
||||
|
||||
ConfigCache.Agent.Network.Public = p
|
||||
|
||||
SaveConfig()
|
||||
|
||||
}
|
||||
|
||||
71
agent-wdd/log/SimpleLog.go
Normal file
71
agent-wdd/log/SimpleLog.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
colorReset = "\033[0m"
|
||||
colorRed = "\033[31m"
|
||||
colorGreen = "\033[32m"
|
||||
colorYellow = "\033[33m"
|
||||
colorBlue = "\033[34m"
|
||||
)
|
||||
|
||||
func main() {
|
||||
Debug("Debug message: %s", "connection established")
|
||||
Info("System %s", "started successfully")
|
||||
Warning("Disk space at %d%%", 85)
|
||||
Error("Failed to %s", "load config")
|
||||
}
|
||||
|
||||
func Debug(format string, args ...interface{}) {
|
||||
log("DEBUG", colorBlue, format, args...)
|
||||
}
|
||||
|
||||
func Info(format string, args ...interface{}) {
|
||||
log("INFO", colorGreen, format, args...)
|
||||
}
|
||||
|
||||
func Warning(format string, args ...interface{}) {
|
||||
log("WARNING", colorYellow, format, args...)
|
||||
}
|
||||
|
||||
func Error(format string, args ...interface{}) {
|
||||
log("ERROR", colorRed, format, args...)
|
||||
}
|
||||
|
||||
func log(level string, color string, format string, args ...interface{}) {
|
||||
// 获取调用者信息(跳过2层调用栈)
|
||||
_, file, line, _ := runtime.Caller(2)
|
||||
|
||||
s := strings.Split(file, "ProjectOctopus")[1]
|
||||
callerInfo := strings.TrimLeft(s, "/") + " "
|
||||
callerInfo += strconv.FormatInt(int64(line), 10)
|
||||
|
||||
timestamp := currentTimeString()
|
||||
message := fmt.Sprintf(format, args...)
|
||||
fmt.Printf("%s %s%-7s%s [%s] %s\n",
|
||||
timestamp,
|
||||
color,
|
||||
level,
|
||||
colorReset,
|
||||
callerInfo,
|
||||
message)
|
||||
}
|
||||
|
||||
func currentTimeString() string {
|
||||
|
||||
// 加载东八区时区
|
||||
loc, _ := time.LoadLocation("Asia/Shanghai")
|
||||
|
||||
// 获取当前时间并转换为东八区时间
|
||||
now := time.Now().In(loc)
|
||||
// 格式化为 "2006-01-02 15:04:05" 的布局
|
||||
formattedTime := now.Format(time.DateTime)
|
||||
return formattedTime
|
||||
}
|
||||
@@ -2,6 +2,10 @@ package main
|
||||
|
||||
import "agent-wdd/cmd"
|
||||
|
||||
// C:\Users\wdd\go\bin\gox.exe -osarch="linux/amd64" -output "build/agent-wdd_{{.OS}}_{{.Arch}}"
|
||||
// rm -rf agent-wdd_linux_amd64
|
||||
// chmod +x agent-wdd_linux_amd64 && ./agent-wdd_linux_amd64 version
|
||||
|
||||
func main() {
|
||||
|
||||
// WDD 启动
|
||||
|
||||
323
agent-wdd/utils/FileUtils.go
Normal file
323
agent-wdd/utils/FileUtils.go
Normal file
@@ -0,0 +1,323 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"agent-wdd/log"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// AppendFileToFile 将源文件的内容添加到目标文件
|
||||
func AppendFileToFile(sourceFile, targetFile string) bool {
|
||||
|
||||
// 打开源文件
|
||||
source, err := os.Open(sourceFile)
|
||||
if err != nil {
|
||||
log.Error("[BasicAppendSourceToFile] - error open source file => %s, error is %s", sourceFile, err.Error())
|
||||
return false
|
||||
}
|
||||
defer source.Close()
|
||||
|
||||
// 打开目标文件,如果不存在则创建,如果存在则在末尾追加
|
||||
target, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Error("[BasicAppendSourceToFile] - error open target file => %s, error is %s", sourceFile, err.Error())
|
||||
return false
|
||||
}
|
||||
defer target.Close()
|
||||
|
||||
// 将源文件内容复制到目标文件
|
||||
_, err = io.Copy(target, source)
|
||||
if err != nil {
|
||||
log.Error("[BasicAppendSourceToFile] - Error appending to target file: %s", err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AppendOverwriteContentToFile 向目标文件中写入一些内容,覆盖源文件
|
||||
func AppendOverwriteContentToFile(content string, targetFile string) bool {
|
||||
|
||||
err := os.Remove(targetFile)
|
||||
if err != nil {
|
||||
log.Warning("[BasicAppendOverwriteContentToFile] - Error removing file: %s , error is %s", targetFile, err.Error())
|
||||
}
|
||||
|
||||
return AppendContentToFile(content, targetFile)
|
||||
}
|
||||
|
||||
// AppendContentToFile 向目标文件(targetFile 文件的绝对路径)中追加写入一些内容, 如果文件不存在,那么就创建相应的目录及文件
|
||||
func AppendContentToFile(content string, targetFile string) bool {
|
||||
|
||||
// 创建目标文件的目录(递归创建)
|
||||
dir := filepath.Dir(targetFile)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// 打开文件用于追加。如果文件不存在,将会创建一个新文件。
|
||||
file, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Error("[BasicAppendContentToFile] - Error opening file: %s , error is %s", targetFile, err.Error())
|
||||
return false
|
||||
}
|
||||
defer file.Close() // 确保文件最终被关闭
|
||||
|
||||
// 写入内容到文件
|
||||
// 内容非空时执行写入操作
|
||||
if content != "" {
|
||||
if _, err := file.WriteString(content); err != nil {
|
||||
log.Error("[BasicAppendContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AppendOverwriteListContentToFile 将一个字符串列表中的内容,一行一行的写入文件中
|
||||
func AppendOverwriteListContentToFile(contentList []string, targetFile string) bool {
|
||||
|
||||
err := os.Remove(targetFile)
|
||||
if err != nil {
|
||||
log.Warning("[AppendOverwriteListContentToFile] - Error removing file: %s , error is %s", targetFile, err.Error())
|
||||
}
|
||||
|
||||
// 打开文件用于追加。如果文件不存在,将会创建一个新文件。
|
||||
file, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Error("[AppendOverwriteListContentToFile] - Error opening file: %s , error is %s", targetFile, err.Error())
|
||||
return false
|
||||
}
|
||||
defer file.Close() // 确保文件最终被关闭
|
||||
|
||||
// 写入内容到文件
|
||||
for _, contentLine := range contentList {
|
||||
//bytes, _ := json.Marshal(contentLine)
|
||||
if _, err := file.WriteString(contentLine + "\n"); err != nil {
|
||||
log.Error("[AppendOverwriteListContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AppendK8sYamlWithSplitLineToFile 专门为k8s的yaml文件设计的,在每次写入内容之前,先写入一行分隔符
|
||||
func AppendK8sYamlWithSplitLineToFile(content string, targetFile string) bool {
|
||||
|
||||
// 打开文件用于追加。如果文件不存在,将会创建一个新文件。
|
||||
file, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Error("[BasicAppendContentToFile] - Error opening file: %s , error is %s", targetFile, err.Error())
|
||||
return false
|
||||
}
|
||||
defer file.Close() // 确保文件最终被关闭
|
||||
|
||||
// 写入内容到文件
|
||||
if _, err := file.WriteString("---"); err != nil {
|
||||
log.Error("[BasicAppendContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
|
||||
return false
|
||||
}
|
||||
if _, err := file.WriteString(content); err != nil {
|
||||
log.Error("[BasicAppendContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AppendNullOverWriteToFile 清空一个文件
|
||||
func AppendNullOverWriteToFile(targetFile string) bool {
|
||||
|
||||
// 使用os.O_TRUNC清空文件内容
|
||||
file, err := os.OpenFile(targetFile, os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Error("[AppendNullOverWriteToFile] - Error opening file: %s, error is %s", targetFile, err.Error())
|
||||
return false
|
||||
}
|
||||
defer file.Close() // 确保在函数退出前关闭文件
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func WordSpaceCompletion(source string, totalLength int) string {
|
||||
sourceLength := len(source)
|
||||
|
||||
if sourceLength >= totalLength {
|
||||
return source
|
||||
}
|
||||
|
||||
for i := 0; i < totalLength-sourceLength; i++ {
|
||||
source += " "
|
||||
}
|
||||
|
||||
return source
|
||||
}
|
||||
|
||||
// IsDirOrFile 如果是目录则返回true,是文件则返回false
|
||||
func IsDirOrFile(path string) bool {
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return info.IsDir()
|
||||
}
|
||||
|
||||
// FileExists 文件存在返回true,不存在返回false,如果文件是一个目录,也返回false
|
||||
func FileExists(fileFullPath string) bool {
|
||||
info, err := os.Stat(fileFullPath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
// FileOrFolderExists 文件或者目录是否返回true,不存在返回false
|
||||
func FileOrFolderExists(fileFullPath string) bool {
|
||||
_, err := os.Stat(fileFullPath)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
// FileExistAndNotNull 文件不为空返回true 文件为空返回false
|
||||
func FileExistAndNotNull(filename string) bool {
|
||||
|
||||
// Check if the file exists
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
log.Debug("文件 %s 不存在!", filename)
|
||||
return false
|
||||
}
|
||||
|
||||
// Open the file for reading
|
||||
file, err := os.Open(filename)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
log.Debug("文件 %s 打开有误!", filename)
|
||||
return false // Handle error according to your needs
|
||||
}
|
||||
|
||||
// Get the file size
|
||||
info, _ := file.Stat()
|
||||
size := info.Size()
|
||||
|
||||
// Check if the file is not empty
|
||||
return size > 0
|
||||
}
|
||||
|
||||
// ListAllFileInFolder 列出一个目录中的所有文件,返回文件名,忽略folder,不带全路径
|
||||
func ListAllFileInFolder(folderName string) ([]string, error) {
|
||||
return listAllFileInFolderWithFullPath(folderName, false)
|
||||
}
|
||||
|
||||
func ListAllFileInFolderWithFullPath(folderName string) ([]string, error) {
|
||||
return listAllFileInFolderWithFullPath(folderName, true)
|
||||
}
|
||||
|
||||
func listAllFileInFolderWithFullPath(folderName string, fullPath bool) ([]string, error) {
|
||||
files := make([]string, 0)
|
||||
err := filepath.Walk(folderName, func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
if fullPath {
|
||||
files = append(files, path)
|
||||
} else {
|
||||
files = append(files, info.Name())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func RemoveFolderComplete(folderName string) bool {
|
||||
|
||||
err := filepath.Walk(folderName,
|
||||
func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return os.Remove(path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
err = os.RemoveAll(folderName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ReadAllContentFromFile(fileFullPath string) (result []string) {
|
||||
|
||||
f, err := os.Open(fileFullPath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return result
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if len(line) > 0 { // ignore empty lines
|
||||
result = append(result, line)
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
fmt.Println(err)
|
||||
return result
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// MoveFolerToAnother 将源文件夹中除了子文件夹外的所有文件移动到目标文件夹
|
||||
func MoveFolerToAnother(srcDir, dstDir string) error {
|
||||
// 读取源文件夹中的所有条目
|
||||
entries, err := os.ReadDir(srcDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取源文件夹失败: %w", err)
|
||||
}
|
||||
|
||||
// 遍历所有条目
|
||||
for _, entry := range entries {
|
||||
// 跳过子文件夹
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
// 构造源文件路径和目标文件路径
|
||||
srcPath := filepath.Join(srcDir, entry.Name())
|
||||
dstPath := filepath.Join(dstDir, entry.Name())
|
||||
|
||||
// 移动文件
|
||||
if err := os.Rename(srcPath, dstPath); err != nil {
|
||||
return fmt.Errorf("移动文件失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCurrentUserFolder 获取运行环境当前用户的根目录
|
||||
func GetCurrentUserFolder() string {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return usr.HomeDir
|
||||
}
|
||||
24
agent-wdd/utils/TimeUtils.go
Normal file
24
agent-wdd/utils/TimeUtils.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const defaultTimeString = "2011-11-11 11:11:11"
|
||||
|
||||
func CurrentTimeString() string {
|
||||
|
||||
// 加载东八区时区
|
||||
loc, err := time.LoadLocation("Asia/Shanghai")
|
||||
if err != nil {
|
||||
fmt.Println("无法加载时区:", err)
|
||||
return defaultTimeString
|
||||
}
|
||||
|
||||
// 获取当前时间并转换为东八区时间
|
||||
now := time.Now().In(loc)
|
||||
// 格式化为 "2006-01-02 15:04:05" 的布局
|
||||
formattedTime := now.Format(time.DateTime)
|
||||
return formattedTime
|
||||
}
|
||||
Reference in New Issue
Block a user