Skip to content
This repository was archived by the owner on Apr 24, 2022. It is now read-only.

Commit 5502887

Browse files
committedMay 9, 2018
Implement built-in http server for miner state reports
1 parent 26638af commit 5502887

File tree

4 files changed

+156
-1
lines changed

4 files changed

+156
-1
lines changed
 

‎ethminer/MinerAux.h

+8
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#endif
5555
#if API_CORE
5656
#include <libapicore/Api.h>
57+
#include <libapicore/httpServer.h>
5758
#endif
5859

5960
using namespace std;
@@ -391,6 +392,10 @@ class MinerCLI
391392
{
392393
m_api_port = atoi(argv[++i]);
393394
}
395+
else if ((arg == "--http-port") && i + 1 < argc)
396+
{
397+
m_http_port = atoi(argv[++i]);
398+
}
394399
#endif
395400
#if ETH_ETHASHCL
396401
else if (arg == "--opencl-platform" && i + 1 < argc)
@@ -844,6 +849,7 @@ class MinerCLI
844849
#if API_CORE
845850
<< " API core configuration:" << endl
846851
<< " --api-port Set the api port, the miner should listen to. Use 0 to disable. Default=0, use negative numbers to run in readonly mode. for example -3333." << endl
852+
<< " --http-port Set the web api port, the miner should listen to. Use 0 to disable. Default=0. Data shown depends on HWMON setting." << endl
847853
#endif
848854
;
849855
}
@@ -982,6 +988,7 @@ class MinerCLI
982988

983989
#if API_CORE
984990
Api api(this->m_api_port, f);
991+
http_server.run(m_http_port, &f, m_show_hwmonitors, m_show_power);
985992
#endif
986993

987994
// Start PoolManager
@@ -1058,6 +1065,7 @@ class MinerCLI
10581065
bool m_show_power = false;
10591066
#if API_CORE
10601067
int m_api_port = 0;
1068+
int m_http_port = 0;
10611069
#endif
10621070

10631071
bool m_report_stratum_hashrate = false;

‎libapicore/CMakeLists.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
set(SOURCES
22
Api.h Api.cpp
33
ApiServer.h ApiServer.cpp
4+
httpServer.cpp httpServer.h
45
)
56

7+
hunter_add_package(mongoose)
8+
find_package(mongoose CONFIG REQUIRED)
9+
610
add_library(apicore ${SOURCES})
7-
target_link_libraries(apicore PRIVATE ethcore devcore ethminer-buildinfo libjson-rpc-cpp::server)
11+
target_link_libraries(apicore PRIVATE ethcore devcore ethminer-buildinfo libjson-rpc-cpp::server mongoose::mongoose)
812
target_include_directories(apicore PRIVATE ..)

‎libapicore/httpServer.cpp

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <chrono>
2+
#include <thread>
3+
#include <mongoose/mongoose.h>
4+
#include <limits.h>
5+
#include "httpServer.h"
6+
#include "libdevcore/Log.h"
7+
#include "libdevcore/Common.h"
8+
#include "ethminer-buildinfo.h"
9+
10+
#ifndef HOST_NAME_MAX
11+
#define HOST_NAME_MAX 255
12+
#endif
13+
14+
using namespace dev;
15+
using namespace eth;
16+
17+
httpServer http_server;
18+
19+
void httpServer::tableHeader(stringstream& ss, unsigned columns)
20+
{
21+
auto info = ethminer_get_buildinfo();
22+
char hostName[HOST_NAME_MAX + 1];
23+
gethostname(hostName, HOST_NAME_MAX + 1);
24+
string l = m_farm->farmLaunchedFormatted();
25+
ss <<
26+
"<head><title>" << hostName <<
27+
"</title><style>tr:nth-child(even){background-color:Gainsboro;}</style>"
28+
"<meta http-equiv=refresh content=30></head><body><table width=\"50%\" border=1 cellpadding=2 cellspacing=0 align=center>"
29+
"<tr valign=top align=center style=background-color:Gold><th colspan=" << columns << ">" << info->project_version <<
30+
" on " << hostName << " - " << l << "</th></tr>";
31+
}
32+
33+
34+
void httpServer::getstat1(stringstream& ss)
35+
{
36+
using namespace std::chrono;
37+
WorkingProgress p = m_farm->miningProgress(m_show_hwmonitors, m_show_power);
38+
SolutionStats s = m_farm->getSolutionStats();
39+
tableHeader(ss, 5);
40+
ss <<
41+
"<tr valign=top align=center style=background-color:Yellow>"
42+
"<th>GPU</th><th>Hash Rate (mh/s)</th><th>Temperature (C)</th><th>Fan Percent.</th><th>Power (W)</th></tr>";
43+
double hashSum = 0.0;
44+
double powerSum = 0.0;
45+
for (unsigned i = 0; i < p.minersHashes.size(); i++) {
46+
double rate = p.minerRate(p.minersHashes[i]) / 1000000.0;
47+
hashSum += rate;
48+
ss <<
49+
"<tr valign=top align=center><td>" << i <<
50+
"</td><td>" << fixed << setprecision(2) << rate;
51+
if (m_show_hwmonitors && (i < p.minerMonitors.size())) {
52+
HwMonitor& hw(p.minerMonitors[i]);
53+
powerSum += hw.powerW;
54+
ss << "</td><td>" << hw.tempC << "</td><td>" << hw.fanP << "</td><td>";
55+
if (m_show_power)
56+
ss << fixed << setprecision(0) << hw.powerW;
57+
else
58+
ss << '-';
59+
ss << "</td></tr>";
60+
}
61+
else
62+
ss << "</td><td>-</td><td>-</td><td>-</td></tr>";
63+
}
64+
ss <<
65+
"<tr valign=top align=center style=\"background-color:yellow\"><th>Total</th><td>" <<
66+
fixed << setprecision(2) << hashSum << "</td><td colspan=2>Solutions: " << s <<
67+
"</td><td>";
68+
if (m_show_power)
69+
ss << fixed << setprecision(0) << powerSum;
70+
else
71+
ss << '-';
72+
ss << "</td></tr></table></body></html>";
73+
}
74+
75+
static void ev_handler(struct mg_connection* c, int ev, void* p)
76+
{
77+
78+
if (ev == MG_EV_HTTP_REQUEST) {
79+
struct http_message* hm = (struct http_message*) p;
80+
if (mg_vcmp(&hm->uri, "/getstat1") && mg_vcmp(&hm->uri, "/"))
81+
mg_http_send_error(c, 404, nullptr);
82+
else {
83+
stringstream content;
84+
http_server.getstat1(content);
85+
mg_send_head(c, 200, (int)content.str().length(), "Content-Type: text/html");
86+
mg_printf(c, "%.*s", (int)content.str().length(), content.str().c_str());
87+
}
88+
}
89+
}
90+
91+
void httpServer::run(unsigned short port, dev::eth::Farm* farm, bool show_hwmonitors, bool show_power)
92+
{
93+
if (port == 0)
94+
return;
95+
m_farm = farm;
96+
m_port = to_string(port);
97+
m_show_hwmonitors = show_hwmonitors;
98+
m_show_power = show_power;
99+
new thread(bind(&httpServer::run_thread, this));
100+
}
101+
102+
void httpServer::run_thread()
103+
{
104+
struct mg_mgr mgr;
105+
struct mg_connection* c;
106+
107+
mg_mgr_init(&mgr, NULL);
108+
cnote << "Starting web server on port " << m_port;
109+
c = mg_bind(&mgr, m_port.c_str(), ev_handler);
110+
if (c == NULL) {
111+
cwarn << "Failed to create web listener";
112+
return;
113+
}
114+
115+
// Set up HTTP server parameters
116+
mg_set_protocol_http_websocket(c);
117+
118+
for (;;)
119+
mg_mgr_poll(&mgr, 1000);
120+
}
121+

‎libapicore/httpServer.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#include <thread>
4+
#include <libethcore/Farm.h>
5+
6+
class httpServer
7+
{
8+
public:
9+
void run(unsigned short port, dev::eth::Farm* farm, bool show_hwmonitors, bool show_power);
10+
void run_thread();
11+
void getstat1(stringstream& ss);
12+
13+
dev::eth::Farm* m_farm;
14+
std::string m_port;
15+
private:
16+
void tableHeader(stringstream& ss, unsigned columns);
17+
bool m_show_hwmonitors;
18+
bool m_show_power;
19+
};
20+
21+
extern httpServer http_server;
22+

0 commit comments

Comments
 (0)
This repository has been archived.