summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/daemon/angelbeats/Makefile8
-rw-r--r--pttbbs/daemon/angelbeats/abc.c22
-rw-r--r--pttbbs/daemon/angelbeats/angelbeats.c73
-rw-r--r--pttbbs/include/daemons.h1
-rw-r--r--pttbbs/util/angel.c53
5 files changed, 114 insertions, 43 deletions
diff --git a/pttbbs/daemon/angelbeats/Makefile b/pttbbs/daemon/angelbeats/Makefile
index 435b9625..8d80ada6 100644
--- a/pttbbs/daemon/angelbeats/Makefile
+++ b/pttbbs/daemon/angelbeats/Makefile
@@ -2,7 +2,6 @@
SRCROOT= ../..
.include "$(SRCROOT)/pttbbs.mk"
-PROGS= angelbeats
PROGRAMS= angelbeats abc
UTILDIR= $(SRCROOT)/util
UTILOBJ= $(UTILDIR)/util_var.o
@@ -20,15 +19,18 @@ all: ${PROGRAMS}
.cpp.o:
$(CXX) $(CXXFLAGS) -c $*.cpp
+ctags:
+ ctags *.[ch] $(SRCROOT)/include/*.h $(SRCROOT)/common/*/*.[ch]
+
angelbeats: angelbeats.o
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $> $(UTILOBJ) $(LDLIBS)
abc: abc.o
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $> $(UTILOBJ) $(LDLIBS)
-install: $(PROGS)
+install: $(PROGRAMS)
install -d $(BBSHOME)/bin/
- install -c -m 755 $(PROGS) $(BBSHOME)/bin/
+ install -c -m 755 $(PROGRAMS) $(BBSHOME)/bin/
mv -f $(BBSHOME)/bin/angelbeats $(BBSHOME)/bin/angelbeats.`date '+%m%d%H%M'`
ln -sv $(BBSHOME)/bin/angelbeats.`date '+%m%d%H%M'` $(BBSHOME)/bin/angelbeats
diff --git a/pttbbs/daemon/angelbeats/abc.c b/pttbbs/daemon/angelbeats/abc.c
index 8420318e..ed9a7bb3 100644
--- a/pttbbs/daemon/angelbeats/abc.c
+++ b/pttbbs/daemon/angelbeats/abc.c
@@ -29,20 +29,15 @@ int main(int argc, char *argv[])
}
// start commands
- if (strcmp(argv[1], "reload") == 0)
- {
+ if (strcmp(argv[1], "reload") == 0) {
req.operation = ANGELBEATS_REQ_RELOAD;
- }
- else if (strcmp(argv[1], "suggest") == 0)
- {
+ } else if (strcmp(argv[1], "suggest") == 0) {
req.operation = ANGELBEATS_REQ_SUGGEST;
if (argc > 2) {
req.operation = ANGELBEATS_REQ_SUGGEST_AND_LINK;
req.master_uid = searchuser(argv[2], NULL);
}
- }
- else if (strcmp(argv[1], "unlink") == 0)
- {
+ } else if (strcmp(argv[1], "unlink") == 0) {
if (argc != 3) {
printf("need target id.\n");
return -1;
@@ -54,9 +49,7 @@ int main(int argc, char *argv[])
printf("invalid user id: %s\n", argv[2]);
return -1;
}
- }
- else if (strcmp(argv[1], "report") == 0)
- {
+ } else if (strcmp(argv[1], "report") == 0) {
req.operation = ANGELBEATS_REQ_REPORT;
if (argc > 2 && !(req.angel_uid = searchuser(argv[2], NULL))) {
printf("invalid user id: %s\n", argv[2]);
@@ -64,9 +57,12 @@ int main(int argc, char *argv[])
}
} else if (strcmp(argv[1], "list") == 0) {
req.operation = ANGELBEATS_REQ_GET_ONLINE_LIST;
- }
- else
+ } else if (strcmp(argv[1], "perf") == 0) {
+ req.operation = ANGELBEATS_REQ_EXPORT_PERF;
+ } else {
+ fprintf(stderr, "Sorry, unknown command: %s\n", argv[1]);
return 0;
+ }
req.cb = sizeof(req);
if (towrite(fd, &req, sizeof(req)) != sizeof(req)) {
diff --git a/pttbbs/daemon/angelbeats/angelbeats.c b/pttbbs/daemon/angelbeats/angelbeats.c
index bbb91cc8..56900f82 100644
--- a/pttbbs/daemon/angelbeats/angelbeats.c
+++ b/pttbbs/daemon/angelbeats/angelbeats.c
@@ -50,13 +50,26 @@ static int debug = 0;
#define ANGELBEATS_ACTIVITY_MERGE_PERIOD (15)
#endif
+#ifndef ANGELBEATS_PERF_OUTPUT_FILE
+#define ANGELBEATS_PERF_OUTPUT_FILE BBSHOME "/log/angel_perf.txt"
+#endif
//////////////////////////////////////////////////////////////////////////////
// AngelInfo list operation
+#ifndef ANGEL_LIST_INIT_SIZE
#define ANGEL_LIST_INIT_SIZE (250) // usually angels are 200~250
+#endif
typedef struct {
+ int samples;
+ int pause1;
+ int pause2;
+ // TODO add number of being asked, and providing replies.
+} PerfData;
+
+typedef struct {
+ PerfData perf;
time_t last_activity; // last known activity from master
time_t last_assigned; // last time being assigned with new master
int uid;
@@ -196,6 +209,7 @@ int
suggest_online_angel(int master_uid) {
size_t i;
int is_pause, logins;
+ int uid = 0;
for (i = 0; i < g_angel_list_size; i++) {
AngelInfo *kanade = g_angel_list + i;
@@ -204,11 +218,19 @@ suggest_online_angel(int master_uid) {
if (kanade->uid == master_uid)
continue;
- // return if angel is online and not paused.
- if (get_angel_state(kanade, &is_pause, &logins) && !is_pause)
- return kanade->uid;
+ if (!get_angel_state(kanade, &is_pause, &logins))
+ continue;
+
+ // update perf data
+ kanade->perf.samples++;
+ kanade->perf.pause1 += (is_pause == 1);
+ kanade->perf.pause2 += (is_pause == 2);
+
+ // select if angel is online and not paused.
+ if (!uid && !is_pause)
+ uid = kanade->uid;
}
- return 0;
+ return uid;
}
int
@@ -330,7 +352,10 @@ create_angel_report(int myuid, angel_beats_report *prpt) {
if (is_pause)
fprintf(stderr, "[set PAUSE (%d)] ", is_pause);
fprintf(stderr,
+ "{samples=%d, pause1=%d, pause2=%d} "
"(masters=%d, activity=%d, assigned=%d, logins=%d)\n",
+ kanade->perf.samples, kanade->perf.pause1,
+ kanade->perf.pause2,
kanade->masters, (int)kanade->last_activity,
(int)kanade->last_assigned, logins);
}
@@ -391,6 +416,29 @@ fill_online_angel_list(angel_beats_uid_list *list) {
return list->angels;
}
+void print_dash(FILE *fp, int len, const char *prefix) {
+ if (prefix)
+ fputs(prefix, fp);
+ while (len-- > 0)
+ fputc('-', fp);
+ fputc('\n', fp);
+}
+
+void export_perf_data(FILE *fp) {
+ size_t i = 0;
+ time4_t clk = time4(0);
+ AngelInfo *kanade = g_angel_list;
+ fprintf(fp, "# Angel Performance Data (%s)\n", Cdatelite(&clk));
+ fprintf(fp, "# No. %-*s Samples Pause1 Pause2\n# ", IDLEN, "UserID");
+ print_dash(fp, 70, "# ");
+ for (i = 0; i < g_angel_list_size; i++, kanade++) {
+ fprintf(fp, "%4lu. %-*s %7d %7d %7d\n", i + 1, IDLEN, kanade->userid,
+ kanade->perf.samples, kanade->perf.pause1, kanade->perf.pause2);
+ // reset perf data
+ memset(&kanade->perf, 0, sizeof(kanade->perf));
+ }
+ print_dash(fp, 70, "# ");
+}
//////////////////////////////////////////////////////////////////////////////
// network libevent
@@ -469,6 +517,19 @@ client_cb(int fd, short event, void *arg) {
if (touch_angel_activity(data.angel_uid))
angel_list_sort();
break;
+ case ANGELBEATS_REQ_EXPORT_PERF:
+ fprintf(stderr, "%s export_perf_data\n", Cdatelite(&clk));
+ {
+ FILE *fp = fopen(ANGELBEATS_PERF_OUTPUT_FILE, "at");
+ if (fp) {
+ export_perf_data(fp);
+ fclose(fp);
+ } else {
+ fprintf(stderr, "%s ERROR: cannot output perf: %s\n",
+ Cdatelite(&clk), ANGELBEATS_PERF_OUTPUT_FILE);
+ }
+ }
+ break;
case ANGELBEATS_REQ_REPORT:
fprintf(stderr, "%s report by [%s]\n", Cdatelite(&clk), master_uid);
{
@@ -492,6 +553,10 @@ client_cb(int fd, short event, void *arg) {
goto end;
}
break;
+ default:
+ fprintf(stderr, "%s UNKNOWN REQUEST (%d)\n", Cdatelite(&clk),
+ data.operation);
+ break;
}
write(fd, &data, sizeof(data));
diff --git a/pttbbs/include/daemons.h b/pttbbs/include/daemons.h
index f670644b..bea523e3 100644
--- a/pttbbs/include/daemons.h
+++ b/pttbbs/include/daemons.h
@@ -68,6 +68,7 @@ enum ANGELBEATS_OPERATIONS {
ANGELBEATS_REQ_REMOVE_LINK,
ANGELBEATS_REQ_HEARTBEAT,
ANGELBEATS_REQ_GET_ONLINE_LIST,
+ ANGELBEATS_REQ_EXPORT_PERF,
};
typedef struct {
diff --git a/pttbbs/util/angel.c b/pttbbs/util/angel.c
index 780af2f0..a893d7c3 100644
--- a/pttbbs/util/angel.c
+++ b/pttbbs/util/angel.c
@@ -7,7 +7,6 @@ int main(){ return 0; }
int total[MAX_USERS + 1];
int (*list)[2];
-int nReport = 50;
int count;
char* mailto = "SYSOP";
@@ -19,14 +18,25 @@ void slurp(FILE* to, FILE* from);
int main(int argc, char* argv[]){
if (argc > 1)
mailto = argv[1];
- if (argc > 2)
- nReport = atoi(argv[2]);
readData();
sendResult();
return 0;
}
+void appendLogFile(FILE *output,
+ const char *filename,
+ const char *prefix) {
+ FILE *fp = fopen(filename, "r");
+ if (!fp)
+ return;
+ remove(filename);
+
+ fputs(prefix, output);
+ slurp(output, fp);
+ fclose(fp);
+}
+
void readData(){
int i, j;
int k;
@@ -53,9 +63,6 @@ void readData(){
}
fclose(fp);
- if(nReport > count)
- nReport = count;
-
list = (int(*)[2]) malloc(count * sizeof(int[2]));
k = j = 0;
for (i = 1; i <= MAX_USERS; ++i)
@@ -107,30 +114,30 @@ void sendResult(){
fprintf(fp, "作者: " BBSMNAME " 站方統計\n"
"標題: 小天使統計資料\n"
"時間: %s\n"
- "\n現在全站小天使有 %d 位\n"
- "\n小主人人數最多的 %d 位小天使:\n",
- ctime4(&t), count, nReport);
- for (i = 0; i < nReport; ++i)
+ "\n現在全站小天使有 %d 位:\n",
+ ctime4(&t), count);
+ for (i = 0; i < count; ++i)
fprintf(fp, "%15s %5d 人\n", SHM->userid[list[i][1] - 1], list[i][0]);
- if (i % 4 != 0) fputc('\n', fp);
-
- {
- FILE* changefp = fopen(BBSHOME "/log/changeangel.log", "r");
- if (changefp) {
- remove(BBSHOME "/log/changeangel.log");
-
- fputs("\n== 本周更換小天使紀錄 ==\n", fp);
- slurp(fp, changefp);
- fclose(changefp);
- }
- }
+ if (i % 4 != 0)
+ fputc('\n', fp);
+
+ appendLogFile(fp, BBSHOME "/log/angel_perf.txt",
+ "\n== 本周小天使活動資料記錄 ==\n"
+ " (說明: Samples 指的是新小主人找天使時有在線上的次數\n"
+ " Pause1 指的是 Samples 中有幾次神諭呼叫器設停收\n"
+ " Pause2 指的是 Samples 中有幾次神諭呼叫器設關閉\n"
+ " 因此,Samples 與其它人差太多代表不常上線\n"
+ " Pause2 接近 Samples 代表此天使都在打混)\n"
+ );
+ appendLogFile(fp, BBSHOME "/log/changeangel.log",
+ "\n== 本周更換小天使記錄 ==\n");
fputs("\n--\n\n 本資料由 angel 程式產生\n\n", fp);
fclose(fp);
strcpy(header.title, "小天使統計資料");
strcpy(header.owner, "站方統計");
- sprintf(filename, BBSHOME "/home/%c/%s/.DIR", mailto[0], mailto);
+ sethomedir(filename, mailto);
append_record(filename, &header, sizeof(header));
mailalertuser(mailto);
}