tea time
This commit is contained in:
commit
a852b4e489
2 changed files with 146 additions and 0 deletions
143
finder.py
Normal file
143
finder.py
Normal file
|
@ -0,0 +1,143 @@
|
|||
import paramiko
|
||||
import csv
|
||||
import re
|
||||
|
||||
# Define credentials for different OS types
|
||||
credentials = {
|
||||
"stock": [("miner", "miner"), ("root", "root")],
|
||||
"braiins": [("root", "root")],
|
||||
"luxos": [("root", "root")],
|
||||
"vnish": [("user", "password")] # Replace with correct credentials
|
||||
}
|
||||
|
||||
# List of error keywords
|
||||
error_keywords = [
|
||||
"ERROR_TEMP_TOO_HIGH",
|
||||
"ERROR_HASHRATE_TOO_LOW",
|
||||
"ERROR_NETWORK_DISCONNECTED",
|
||||
"ERROR_POWER_LOST: power voltage rise or drop",
|
||||
"SWEEP_STRING",
|
||||
"_pic_write_iic failed!",
|
||||
"PLL read exceeded wait time",
|
||||
"ERROR_SOC_INIT: soc init failed",
|
||||
"fail to read 0:1",
|
||||
"fail to write 0:1"
|
||||
]
|
||||
|
||||
# Regex pattern for ASIC chip errors
|
||||
asic_pattern = re.compile(r"Chain\[(\d+)\]: find (\d+) asic, times \d+")
|
||||
|
||||
# Function to read IP addresses from a file
|
||||
def read_ips(file_path):
|
||||
with open(file_path, 'r') as file:
|
||||
ips = file.readlines()
|
||||
return [ip.strip() for ip in ips]
|
||||
|
||||
# Function to check log files for keywords and ASIC errors
|
||||
def check_logs(ip, ssh_client):
|
||||
logs = []
|
||||
asic_errors = {}
|
||||
correct_asic_count = {}
|
||||
try:
|
||||
print(f"Checking logs on {ip}")
|
||||
stdin, stdout, stderr = ssh_client.exec_command("find /var/log/ -type f")
|
||||
log_files = stdout.readlines()
|
||||
for log_file in log_files:
|
||||
log_file = log_file.strip()
|
||||
# Check if file should be ignored
|
||||
if log_file.endswith(('tmp', 'utmp', 'btmp', 'wtmp')):
|
||||
continue
|
||||
|
||||
# Check if file is a binary file
|
||||
stdin, stdout, stderr = ssh_client.exec_command(f"file {log_file}")
|
||||
file_type = stdout.read().decode('utf-8')
|
||||
if 'text' not in file_type:
|
||||
continue
|
||||
|
||||
stdin, stdout, stderr = ssh_client.exec_command(f"cat {log_file}")
|
||||
log_content = stdout.read().decode('utf-8', errors='ignore')
|
||||
for keyword in error_keywords:
|
||||
if keyword in log_content:
|
||||
logs.append((log_file, keyword))
|
||||
|
||||
# Check for ASIC chip errors
|
||||
for match in asic_pattern.finditer(log_content):
|
||||
chain, asic_count = match.groups()
|
||||
asic_count = int(asic_count)
|
||||
if chain not in asic_errors:
|
||||
asic_errors[chain] = []
|
||||
asic_errors[chain].append(asic_count)
|
||||
|
||||
# Determine the correct ASIC count for each chain
|
||||
if chain not in correct_asic_count and asic_count > 0:
|
||||
correct_asic_count[chain] = asic_count
|
||||
except Exception as e:
|
||||
print(f"Error checking logs on {ip}: {e}")
|
||||
return logs, asic_errors, correct_asic_count
|
||||
|
||||
# Function to get worker ID
|
||||
def get_worker_id(ssh_client):
|
||||
try:
|
||||
print("Getting worker ID")
|
||||
stdin, stdout, stderr = ssh_client.exec_command("cat /config/cgminer.conf")
|
||||
config_content = stdout.read().decode('utf-8')
|
||||
# Extract the worker ID from the user field
|
||||
match = re.search(r'"user" *: *"[^.]*\.(\w+)"', config_content)
|
||||
if match:
|
||||
worker_id = match.group(1)
|
||||
print("Got worker ID: ", worker_id)
|
||||
else:
|
||||
worker_id = "Unknown"
|
||||
except Exception as e:
|
||||
print(f"Error getting worker ID: {e}")
|
||||
worker_id = "Unknown"
|
||||
return worker_id
|
||||
|
||||
# Main function to iterate over IPs and check for errors
|
||||
def main():
|
||||
ips = read_ips('ips.txt')
|
||||
results = []
|
||||
|
||||
for ip in ips:
|
||||
print(f"Processing IP: {ip}")
|
||||
connected = False
|
||||
for os_type, creds in credentials.items():
|
||||
if connected:
|
||||
break
|
||||
for username, password in creds:
|
||||
ssh_client = paramiko.SSHClient()
|
||||
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
try:
|
||||
print(f"Trying {username}:{password} on {ip}")
|
||||
ssh_client.connect(ip, username=username, password=password)
|
||||
connected = True
|
||||
worker_id = get_worker_id(ssh_client)
|
||||
logs, asic_errors, correct_asic_count = check_logs(ip, ssh_client)
|
||||
for log in logs:
|
||||
results.append([worker_id, ip, log[0], log[1]])
|
||||
|
||||
# Check for ASIC chip errors and add to results
|
||||
for chain, counts in asic_errors.items():
|
||||
if counts.count(0) >= 3:
|
||||
results.append([worker_id, ip, "ASIC Error", f"Chain {chain} has {counts.count(0)} failed checks with 0 ASICs found"])
|
||||
elif chain in correct_asic_count:
|
||||
expected_count = correct_asic_count[chain]
|
||||
if any(count != expected_count and count > 0 for count in counts):
|
||||
results.append([worker_id, ip, "ASIC Discrepancy", f"Chain {chain} has varying ASIC counts: {counts}"])
|
||||
|
||||
ssh_client.close()
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"Connection failed for {ip} with {username}:{password} - {e}")
|
||||
ssh_client.close()
|
||||
|
||||
# Write results to CSV
|
||||
print("Writing results to CSV")
|
||||
with open('results.csv', 'w', newline='') as file:
|
||||
writer = csv.writer(file)
|
||||
writer.writerow(["Worker ID", "IP Address", "Log File", "Error"])
|
||||
writer.writerows(results)
|
||||
print("Done")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
3
readme.md
Normal file
3
readme.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Antminer error finder
|
||||
|
||||
Checks for specific strings in log files of Antminer machines. Currently works with stock firmware. Expand to Braiins & LuxOS.
|
Loading…
Reference in a new issue