Add logOutput field to control stdout/stderr logging and update miner management

This commit is contained in:
Snider 2025-11-09 03:10:55 +00:00
parent 98fa23af78
commit 6ac80d211a
7 changed files with 116 additions and 16 deletions

View file

@ -40,8 +40,10 @@ var serveCmd = &cobra.Command{
displayAddr := fmt.Sprintf("%s:%d", displayHost, port)
listenAddr := fmt.Sprintf("%s:%d", host, port)
manager := mining.NewManager()
service := mining.NewService(manager, listenAddr, displayAddr, namespace)
// Use the global manager instance
mgr := getManager() // This ensures we get the manager initialized by initManager
service := mining.NewService(mgr, listenAddr, displayAddr, namespace) // Pass the global manager
// Start the server in a goroutine
go func() {
@ -75,11 +77,83 @@ var serveCmd = &cobra.Command{
return
}
rootCmd.SetArgs(strings.Fields(line))
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
parts := strings.Fields(line)
if len(parts) == 0 {
fmt.Print(">> ")
continue
}
command := strings.ToLower(parts[0])
cmdArgs := parts[1:]
switch command {
case "start":
if len(cmdArgs) < 1 {
fmt.Println("Error: start command requires miner type (e.g., 'start xmrig')")
} else {
minerType := cmdArgs[0]
// Use default pool and wallet for interactive shell for simplicity
config := &mining.Config{
Pool: "pool.hashvault.pro:443",
Wallet: "888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H", // Corrected wallet address
LogOutput: true, // Enable logging for interactive shell
// Add other default config values if necessary
}
miner, err := mgr.StartMiner(minerType, config)
if err != nil {
fmt.Fprintf(os.Stderr, "Error starting miner: %v\n", err)
} else {
fmt.Printf("Miner %s started successfully.\n", miner.GetName())
}
}
case "status":
if len(cmdArgs) < 1 {
fmt.Println("Error: status command requires miner name (e.g., 'status xmrig')")
} else {
minerName := cmdArgs[0]
miner, err := mgr.GetMiner(minerName)
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting miner status: %v\n", err)
} else {
stats, err := miner.GetStats()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting miner stats: %v\n", err)
} else {
fmt.Printf("Miner Status for %s:\n", strings.Title(minerName))
fmt.Printf(" Hash Rate: %d H/s\n", stats.Hashrate)
fmt.Printf(" Shares: %d\n", stats.Shares)
fmt.Printf(" Rejected: %d\n", stats.Rejected)
fmt.Printf(" Uptime: %d seconds\n", stats.Uptime)
fmt.Printf(" Algorithm: %s\n", stats.Algorithm)
}
}
}
case "stop":
if len(cmdArgs) < 1 {
fmt.Println("Error: stop command requires miner name (e.g., 'stop xmrig')")
} else {
minerName := cmdArgs[0]
err := mgr.StopMiner(minerName)
if err != nil {
fmt.Fprintf(os.Stderr, "Error stopping miner: %v\n", err)
} else {
fmt.Printf("Miner %s stopped successfully.\n", minerName)
}
}
case "list":
miners := mgr.ListMiners()
if len(miners) == 0 {
fmt.Println("No miners currently running.")
} else {
fmt.Println("Running Miners:")
for _, miner := range miners {
fmt.Printf(" - %s\n", miner.GetName())
}
}
default:
fmt.Fprintf(os.Stderr, "Unknown command: %s. Only 'start', 'status', 'stop', 'list' are directly supported in this shell.\n", command)
fmt.Fprintf(os.Stderr, "For other commands, please run them directly from your terminal (e.g., 'miner-cli doctor').\n")
}
rootCmd.SetArgs([]string{})
fmt.Print(">> ")
}
}()

View file

@ -416,6 +416,10 @@ const docTemplate = `{
"logFile": {
"type": "string"
},
"logOutput": {
"description": "New field to control stdout/stderr logging",
"type": "boolean"
},
"miner": {
"type": "string"
},

View file

@ -410,6 +410,10 @@
"logFile": {
"type": "string"
},
"logOutput": {
"description": "New field to control stdout/stderr logging",
"type": "boolean"
},
"miner": {
"type": "string"
},

View file

@ -75,6 +75,9 @@ definitions:
type: boolean
logFile:
type: string
logOutput:
description: New field to control stdout/stderr logging
type: boolean
miner:
type: string
nicehash:

View file

@ -27,21 +27,24 @@ func (m *Manager) StartMiner(minerType string, config *Config) (Miner, error) {
return nil, fmt.Errorf("unsupported miner type: %s", minerType)
}
if _, exists := m.miners[miner.GetName()]; exists {
return nil, fmt.Errorf("miner already started: %s", miner.GetName())
// Ensure the miner's internal name is used for map key
minerKey := miner.GetName()
if _, exists := m.miners[minerKey]; exists {
return nil, fmt.Errorf("miner already started: %s", minerKey)
}
if err := miner.Start(config); err != nil {
return nil, err
}
m.miners[miner.GetName()] = miner
m.miners[minerKey] = miner
return miner, nil
}
// StopMiner stops a running miner
func (m *Manager) StopMiner(name string) error {
miner, exists := m.miners[name]
minerKey := strings.ToLower(name) // Normalize input name to lowercase
miner, exists := m.miners[minerKey]
if !exists {
return fmt.Errorf("miner not found: %s", name)
}
@ -50,13 +53,14 @@ func (m *Manager) StopMiner(name string) error {
return err
}
delete(m.miners, name)
delete(m.miners, minerKey)
return nil
}
// GetMiner retrieves a miner by ID
func (m *Manager) GetMiner(name string) (Miner, error) {
miner, exists := m.miners[name]
minerKey := strings.ToLower(name) // Normalize input name to lowercase
miner, exists := m.miners[minerKey]
if !exists {
return nil, fmt.Errorf("miner not found: %s", name)
}

View file

@ -111,6 +111,7 @@ type Config struct {
HealthPrintTime int `json:"healthPrintTime,omitempty"`
NoColor bool `json:"noColor,omitempty"`
Verbose bool `json:"verbose,omitempty"`
LogOutput bool `json:"logOutput,omitempty"` // New field to control stdout/stderr logging
// Misc options
Background bool `json:"background,omitempty"`
@ -177,7 +178,7 @@ type XMRigSummary struct {
SharesTotal uint64 `json:"shares_total"`
} `json:"results"`
Uptime uint64 `json:"uptime"`
Algorithm string `json:"algo"`
Algorithm string `json:"algorithm"`
}
// AvailableMiner represents a miner that is available to be started

View file

@ -295,9 +295,9 @@ func (m *XMRigMiner) Start(config *Config) error {
args = append(args, "--rig-id", config.RigID)
}
// TLS is handled by config file, but --tls-fingerprint is a CLI option
if config.TLS { // If TLS is true in config, ensure --tls is passed if not already in config file
args = append(args, "--tls")
}
//if config.TLS { // If TLS is true in config, ensure --tls is passed if not already in config file
args = append(args, "--tls")
//}
if config.TLSSingerprint != "" {
args = append(args, "--tls-fingerprint", config.TLSSingerprint)
}
@ -467,7 +467,17 @@ func (m *XMRigMiner) Start(config *Config) error {
args = append(args, "--no-dmi")
}
// Print the command being executed for debugging
fmt.Fprintf(os.Stderr, "Executing XMRig command: %s %s\n", m.MinerBinary, strings.Join(args, " "))
m.cmd = exec.Command(m.MinerBinary, args...)
// If LogOutput is true, redirect stdout and stderr
if config.LogOutput {
m.cmd.Stdout = os.Stdout
m.cmd.Stderr = os.Stderr
}
if err := m.cmd.Start(); err != nil {
return err
}