├── README.md
├── index.html
└── log4b.js
/README.md:
--------------------------------------------------------------------------------
1 | # log4b
2 | log for browser, can save and download console log
3 |
4 | idea form: https://github.com/inorganik/debugout.js
5 |
6 | # demo
7 | ```
8 | var Log4b = new log4b();
9 |
10 | Log4b.log('wangduanduan');
11 | Log4b.log(JSON.stringify({name:'wangduan',age:18}));
12 |
13 | Log4b.getLog();
14 | ```
15 | # feature
16 | - log can saved Asynchronous
17 | - log can download
18 | - download file support ie10 and later
19 |
20 | # methods
21 | - getLog: get log show on the console tab
22 | - downloadLog: download the log
23 | - clear: clear all saved log
24 | - log: write log
25 | - lines: get how many lines of log
26 | - search: search a string
27 |
28 | # config
29 | - self.realTimeLoggingOn = true; // log in real time (forwards to console.log)
30 | - self.useTimestamps = false; // insert a timestamp in front of each log
31 | - self.recordLogs = true; // set to false after you're done debugging to avoid the log eating up memory
32 | - self.maxLines = 2500; // if autoTrim is true, this many most recent lines are saved
33 | - self.lineMaxChars = 1500; // if one log is max than lineMaxChars, it will be cut
34 | - self.logFilename = 'log4b.txt'; // filename of log downloaded with downloadLog()
35 | - self.lineBreak = '\n\n';
36 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | log4b
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | readme
14 |
15 |
28 |
29 |
--------------------------------------------------------------------------------
/log4b.js:
--------------------------------------------------------------------------------
1 | (function (log4b) {
2 | window.log4b = window.log4b || log4b
3 | })(function () {
4 | var self = this
5 | // config
6 | self.realTimeLoggingOn = true // log in real time (forwards to console.log)
7 | self.recordLogs = true // set to false after you're done debugging to avoid the log eating up memory
8 | self.maxLines = 2500 // if autoTrim is true, this many most recent lines are saved
9 | self.lineMaxChars = 1500 // if one log is max than lineMaxChars, it will be cut
10 | self.logFilename = 'log4b.txt' // filename of log downloaded with downloadLog()
11 | self.lineBreak = '\n\n'
12 |
13 | // log save
14 | self.output = ''
15 |
16 | this.getLog = function () {
17 | return self.recordLogs ? self.output : 'log recording is off'
18 | }
19 |
20 | this.downloadLog = function () {
21 | var downloadFileName = self.formatTimestamp() + '-' + self.logFilename
22 |
23 | if (window.navigator.msSaveBlob) {
24 | // for ie 10 and later
25 | try {
26 | var blobObject = new Blob([self.output])
27 | window.navigator.msSaveBlob(blobObject, downloadFileName)
28 | } catch (e) {
29 | console.log(e)
30 | }
31 | } else {
32 | var file = 'data:text/plain;charset=utf-8,'
33 | var logFile = self.output
34 | var encoded = encodeURIComponent(logFile)
35 | file += encoded
36 | var a = document.createElement('a')
37 | a.href = file
38 | a.target = '_blank'
39 | a.download = downloadFileName
40 | document.body.appendChild(a)
41 | a.click()
42 | a.remove()
43 | }
44 | }
45 |
46 | this.search = function (string) {
47 | var lines = self.output.split(self.lineBreak)
48 | var rgx = new RegExp(string)
49 | var matched = []
50 |
51 | for (var i = 0; i < lines.length; i++) {
52 | if (rgx.test(lines[i])) {
53 | matched.push('[' + i + ']: ' + lines[i])
54 | }
55 | }
56 | var result = matched.join(self.lineBreak)
57 | return result || 'Nothing found for "' + string + '".'
58 | }
59 |
60 | this.clear = function () {
61 | var clearTime = new Date()
62 | self.output = ''
63 | if (self.realTimeLoggingOn) {
64 | console.log('[log4b.js] clear()')
65 | }
66 | }
67 |
68 | this.log = function (obj) {
69 | if (!self.recordLogs) { return }
70 | (function (obj) {
71 | setTimeout(function () {
72 | self._log(obj)
73 | }, 0)
74 | })(obj)
75 | }
76 |
77 | this._log = function (obj) {
78 | if (typeof obj === 'object') {
79 | obj = JSON.stringify(obj)
80 | }
81 | if (typeof obj !== 'string') {
82 | return
83 | }
84 | if (self.realTimeLoggingOn) {
85 | console.log(obj)
86 | }
87 |
88 | self.output += '[' + self.formatTimestamp() + ']: '
89 | self.output += self.cutExceededChars(obj) + self.lineBreak
90 | self.output = self.trimLog(self.output, self.maxLines)
91 | }
92 |
93 | this.cutExceededChars = function (obj) {
94 | if (obj.length > self.lineMaxChars) {
95 | return obj.substr(0, self.lineMaxChars)
96 | } else {
97 | return obj
98 | }
99 | }
100 |
101 | this.trimLog = function (log, maxLines) {
102 | var lines = log.split(self.lineBreak)
103 | if (lines.length > maxLines) {
104 | lines = lines.slice(lines.length - maxLines)
105 | }
106 | return lines.join(self.lineBreak)
107 | }
108 |
109 | this.lines = function () {
110 | return self.output.split(self.lineBreak).length - 1
111 | }
112 |
113 | this.formatTimestamp = function () {
114 | var timestamp = new Date()
115 | var year = timestamp.getFullYear()
116 | var date = timestamp.getDate()
117 | var month = ('0' + (timestamp.getMonth() + 1)).slice(-2)
118 | var hrs = ('0' + timestamp.getHours()).slice(-2)
119 | var mins = ('0' + timestamp.getMinutes()).slice(-2)
120 | var secs = ('0' + timestamp.getSeconds()).slice(-2)
121 | var ms = timestamp.getMilliseconds()
122 |
123 | return year + '-' + month + '-' + date + ' ' + hrs + ':' + mins + ':' + secs + '.' + ms
124 | }
125 | })
126 |
--------------------------------------------------------------------------------