diff options
-rw-r--r-- | pttbbs/daemon/angelbeats/Makefile | 8 | ||||
-rw-r--r-- | pttbbs/daemon/angelbeats/abc.c | 22 | ||||
-rw-r--r-- | pttbbs/daemon/angelbeats/angelbeats.c | 73 | ||||
-rw-r--r-- | pttbbs/include/daemons.h | 1 | ||||
-rw-r--r-- | pttbbs/util/angel.c | 53 |
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); } |