mirror of
				https://github.com/taigrr/log-socket
				synced 2025-01-18 04:53:14 -08:00 
			
		
		
		
	Compare commits
	
		
			13 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f114098a8c | |||
|  | 2571dbe347 | ||
| 80b80758de | |||
| 0fa4de7961 | |||
| 50c507c8f4 | |||
| e21fb8a614 | |||
| 2492509b6b | |||
| a1e960366e | |||
|  | 430181e3a2 | ||
| 147a8cb30b | |||
|  | 8e044e3993 | ||
|  | e97d37012e | ||
| ebef59a9a8 | 
							
								
								
									
										24
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/ci.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | name: Go package | ||||||
|  | 
 | ||||||
|  | on: [push] | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   test: | ||||||
|  | 
 | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  | 
 | ||||||
|  |       - name: Set up Go | ||||||
|  |         uses: actions/setup-go@v4 | ||||||
|  |         with: | ||||||
|  |           go-version: '1.16' | ||||||
|  | 
 | ||||||
|  |       - name: Install dependencies | ||||||
|  |         run: go get . | ||||||
|  | 
 | ||||||
|  |       - name: Build | ||||||
|  |         run: go build -v ./... | ||||||
|  | 
 | ||||||
|  |       - name: Test | ||||||
|  |         run: go test -v ./... | ||||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| Copyright (C) 2019-2021 by Tai Groot <tai@taigrr.com> | Copyright (C) 2019-2022 by Tai Groot <tai@taigrr.com> | ||||||
| 
 | 
 | ||||||
| Permission to use, copy, modify, and/or distribute this software for any | Permission to use, copy, modify, and/or distribute this software for any | ||||||
| purpose with or without fee is hereby granted. | purpose with or without fee is hereby granted. | ||||||
|  | |||||||
							
								
								
									
										15
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | log-socket | ||||||
|  | ========== | ||||||
|  | `log-socket` is a drop-in replacement for Go's `log` package that allows for streaming of logs via WebSockets. | ||||||
|  | 
 | ||||||
|  | ## Installation | ||||||
|  | To install the library: | ||||||
|  | `go get github.com/taigrr/log-socket` | ||||||
|  | 
 | ||||||
|  | ## Running | ||||||
|  | To run a demo of this library: | ||||||
|  | `go run main.go` | ||||||
|  | 
 | ||||||
|  | This demo will do a sample of every log type and push results to `0.0.0.0:8080`. Once running, you can open a browser and navigate to  | ||||||
|  | `0.0.0.0:8080` to see an example implementation of how logs are streamed. | ||||||
|  | 
 | ||||||
| @ -1,6 +1,7 @@ | |||||||
| package browser | package browser | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	_ "embed" | ||||||
| 	"html/template" | 	"html/template" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strings" | 	"strings" | ||||||
| @ -17,201 +18,7 @@ func LogSocketViewHandler(w http.ResponseWriter, r *http.Request) { | |||||||
| 	homeTemplate.Execute(w, wsResource) | 	homeTemplate.Execute(w, wsResource) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var homeTemplate = template.Must(template.New("").Parse(` | //go:embed viewer.html | ||||||
| <!DOCTYPE html> | var webpage string | ||||||
| <html> |  | ||||||
| <head> |  | ||||||
| <meta charset="utf-8"> |  | ||||||
| </head> |  | ||||||
| <body> |  | ||||||
| <center> |  | ||||||
| <input type="text" id="search" onkeyup="filterTable()" placeholder="Filter..."> |  | ||||||
| <input type="checkbox" id="shouldScroll" checked>Enable Autoscroll<br> |  | ||||||
| <table id="logHeaders" style="text-align:left; width:80%;" > |  | ||||||
| <tbody> |  | ||||||
| <tr class="header"> |  | ||||||
| <th style="width:20%;">TimeStamp</th> |  | ||||||
| <th style="width:5%;">Level</th> |  | ||||||
| <th style="width:65%;">Output</th> |  | ||||||
| <th style="width:10%;">Source</th> |  | ||||||
| </tr> |  | ||||||
| </tbody> |  | ||||||
| </table> |  | ||||||
| 
 | 
 | ||||||
| <div id="tableWrapper"> | var homeTemplate = template.Must(template.New("").Parse(webpage)) | ||||||
| <table id="logs" style="text-align:left; width:100%;" > |  | ||||||
| <tbody id="tbodylogs"> |  | ||||||
| <tr class="header"> |  | ||||||
| <th style="width:20%;"></th> |  | ||||||
| <th style="width:5%;"></th> |  | ||||||
| <th style="width:65%;"></th> |  | ||||||
| <th style="width:10%;"></th> |  | ||||||
| </tr> |  | ||||||
| 
 |  | ||||||
| </tbody> |  | ||||||
| </table> |  | ||||||
| </div> |  | ||||||
| <br> |  | ||||||
| <input class="button" type="button" id="download" value="Download Logs" style="background-color:#3f51b5;"/> |  | ||||||
| <input class="button" type="button" id="delete" value="Delete Logs" style="background-color:#f44336"/> |  | ||||||
| </center> |  | ||||||
| </body> |  | ||||||
| <footer> |  | ||||||
| <style> |  | ||||||
| #tableWrapper{ |  | ||||||
| 	overflow-y: scroll; |  | ||||||
| 	display: flow-root; |  | ||||||
| 	width: 80%; |  | ||||||
| 	height: 80vh; |  | ||||||
| } |  | ||||||
| td,tr{ |  | ||||||
| 	height: min-content; |  | ||||||
| } |  | ||||||
| .button{ |  | ||||||
| 	display: inline-block; |  | ||||||
| 	width: 5vw; |  | ||||||
| 	height: 5vh; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| <script>   |  | ||||||
| var logTable = document.getElementById("logs"); |  | ||||||
| var logTableB = document.getElementById("tbodylogs"); |  | ||||||
| var ws = null; |  | ||||||
| var application = "demo-commit" |  | ||||||
| var logs = []; |  | ||||||
| function sleep(ms) { |  | ||||||
| 	return new Promise(resolve => setTimeout(resolve, ms)); |  | ||||||
| } |  | ||||||
| function download(filename, text) { |  | ||||||
| 	var element = document.createElement('a'); |  | ||||||
| 	element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); |  | ||||||
| 	element.setAttribute('download', filename); |  | ||||||
| 	element.style.display = 'none'; |  | ||||||
| 	document.body.appendChild(element); |  | ||||||
| 	element.click(); |  | ||||||
| 	document.body.removeChild(element); |  | ||||||
| } |  | ||||||
| function openSocket() { |  | ||||||
| 	if (ws) { |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 	ws = new WebSocket("{{.}}"); |  | ||||||
| 	ws.onclose = async function(evt) { |  | ||||||
| 		ws = null; |  | ||||||
| 		while(ws == null){ |  | ||||||
| 			openSocket() |  | ||||||
| 			await sleep(5000); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	ws.onmessage = function(evt) { |  | ||||||
| 		var entry = JSON.parse(evt.data) |  | ||||||
| 		logs.push(entry) |  | ||||||
| 		var row = document.createElement('tr'); |  | ||||||
| 		var ts = document.createElement('td'); |  | ||||||
| 		var tst = document.createTextNode(entry.timestamp); |  | ||||||
| 		ts.appendChild(tst); |  | ||||||
| 		row.appendChild(ts); |  | ||||||
| 		var ts = document.createElement('td'); |  | ||||||
| 		var tst = document.createTextNode(entry.level); |  | ||||||
| 		ts.appendChild(tst); |  | ||||||
| 		row.appendChild(ts); |  | ||||||
| 		var ts = document.createElement('td'); |  | ||||||
| 		var tst = document.createTextNode(entry.output); |  | ||||||
| 		ts.appendChild(tst); |  | ||||||
| 		row.appendChild(ts); |  | ||||||
| 		var ts = document.createElement('td'); |  | ||||||
| 		var tst = document.createTextNode(entry.file); |  | ||||||
| 		ts.appendChild(tst); |  | ||||||
| 		row.appendChild(ts); |  | ||||||
| 		var bg=""; |  | ||||||
| 		switch(entry.level){ |  | ||||||
| 		case "INFO": |  | ||||||
| 			bg="white"; |  | ||||||
| 			break; |  | ||||||
| 		case "ERROR": |  | ||||||
| 			bg="#f44336"; |  | ||||||
| 			break; |  | ||||||
| 		case "WARN": |  | ||||||
| 			bg="#fb8c00" |  | ||||||
| 			break; |  | ||||||
| 		case "TRACE": |  | ||||||
| 			bg="#E1F5FE" |  | ||||||
| 			break; |  | ||||||
| 		case "DEBUG": |  | ||||||
| 			bg="#B3E5FC" |  | ||||||
| 			break; |  | ||||||
| 		default: |  | ||||||
| 			bg="white" |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		row.style.backgroundColor=bg |  | ||||||
| 		logTableB.append(row) |  | ||||||
| 		filterTable() |  | ||||||
| 	} |  | ||||||
| 	ws.onerror = function(evt) { |  | ||||||
| 		if (evt != null && evt.data != null){ |  | ||||||
| 			// handle error here |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| function clearTable(){ |  | ||||||
| 	if(!window.confirm("Are you sure you want to delete all logs?")){ |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	logs = [] |  | ||||||
| 
 |  | ||||||
| 	while (logTableB.childNodes.length > 1) { |  | ||||||
| 		logTableB.removeChild(logTableB.childNodes[1]); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| function filterTable() { |  | ||||||
| 	var cols, input, filter, table, tr, td, i, txtValue, w; |  | ||||||
| 	input = document.getElementById("search"); |  | ||||||
| 	filter = input.value; |  | ||||||
| 	table = logTableB; |  | ||||||
| 	tr = table.getElementsByTagName("tr"); |  | ||||||
| 	for (i = 1; i < tr.length; i++) { |  | ||||||
| 		cols = tr[i].getElementsByTagName("td"); |  | ||||||
| 		var visible = false; |  | ||||||
| 		for (w = 0; w < cols.length; w++){ |  | ||||||
| 			if (!visible && cols[w]) { |  | ||||||
| 				td = cols[w] |  | ||||||
| 				txtValue = td.textContent || td.innerText; |  | ||||||
| 				if (txtValue.indexOf(filter) > -1) { |  | ||||||
| 					visible = true |  | ||||||
| 				}  |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if(visible){ |  | ||||||
| 
 |  | ||||||
| 			tr[i].style.display = ""; |  | ||||||
| 		} else { |  | ||||||
| 
 |  | ||||||
| 			tr[i].style.display = "none"; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| function pageScroll() { |  | ||||||
| 	if (document.getElementById('shouldScroll').checked) { |  | ||||||
| 		document.getElementById('tableWrapper').scrollBy(0,10); |  | ||||||
| 
 |  | ||||||
| 	} |  | ||||||
| 	setTimeout(pageScroll,10); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| document.getElementById("delete").addEventListener("click", function(){ |  | ||||||
| 
 |  | ||||||
| 	clearTable() |  | ||||||
| }, false); |  | ||||||
| document.getElementById("download").addEventListener("click", function(){ |  | ||||||
| 
 |  | ||||||
| 	download(application+'.json',JSON.stringify(logs)); |  | ||||||
| }, false); |  | ||||||
| openSocket(); |  | ||||||
| pageScroll(); |  | ||||||
| </script> |  | ||||||
| 
 |  | ||||||
| </footer> |  | ||||||
| </html> |  | ||||||
| `)) |  | ||||||
|  | |||||||
							
								
								
									
										196
									
								
								browser/viewer.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								browser/viewer.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,196 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="utf-8"> | ||||||
|  | 	</head> | ||||||
|  | 	<body> | ||||||
|  | 		<center> | ||||||
|  | 			<input type="text" id="search" onkeyup="filterTable()" placeholder="Filter..."> | ||||||
|  | 			<input type="checkbox" id="shouldScroll" checked>Enable Autoscroll<br> | ||||||
|  | 			<table id="logHeaders" style="text-align:left; width:80%;" > | ||||||
|  | 				<tbody> | ||||||
|  | 					<tr class="header"> | ||||||
|  | 						<th style="width:20%;">TimeStamp</th> | ||||||
|  | 						<th style="width:5%;">Level</th> | ||||||
|  | 						<th style="width:65%;">Output</th> | ||||||
|  | 						<th style="width:10%;">Source</th> | ||||||
|  | 					</tr> | ||||||
|  | 				</tbody> | ||||||
|  | 			</table> | ||||||
|  | 
 | ||||||
|  | 			<div id="tableWrapper"> | ||||||
|  | 				<table id="logs" style="text-align:left; width:100%;" > | ||||||
|  | 					<tbody id="tbodylogs"> | ||||||
|  | 						<tr class="header"> | ||||||
|  | 							<th style="width:20%;"></th> | ||||||
|  | 							<th style="width:5%;"></th> | ||||||
|  | 							<th style="width:65%;"></th> | ||||||
|  | 							<th style="width:10%;"></th> | ||||||
|  | 						</tr> | ||||||
|  | 
 | ||||||
|  | 					</tbody> | ||||||
|  | 				</table> | ||||||
|  | 			</div> | ||||||
|  | 			<br> | ||||||
|  | 			<input class="button" type="button" id="download" value="Download Logs" style="background-color:#3f51b5;"/> | ||||||
|  | 			<input class="button" type="button" id="delete" value="Delete Logs" style="background-color:#f44336"/> | ||||||
|  | 		</center> | ||||||
|  | 	</body> | ||||||
|  | 	<footer> | ||||||
|  | 		<style> | ||||||
|  | #tableWrapper{ | ||||||
|  | 	overflow-y: scroll; | ||||||
|  | 	display: flow-root; | ||||||
|  | 	width: 80%; | ||||||
|  | 	height: 80vh; | ||||||
|  | } | ||||||
|  | td,tr{ | ||||||
|  | 	height: min-content; | ||||||
|  | } | ||||||
|  | .button{ | ||||||
|  | 	display: inline-block; | ||||||
|  | 	width: 5vw; | ||||||
|  | 	height: 5vh; | ||||||
|  | } | ||||||
|  | 		</style> | ||||||
|  | 		<script>   | ||||||
|  | 			var logTable = document.getElementById("logs"); | ||||||
|  | 			var logTableB = document.getElementById("tbodylogs"); | ||||||
|  | 			var ws = null; | ||||||
|  | 			var application = "demo-commit" | ||||||
|  | 			var logs = []; | ||||||
|  | 			function sleep(ms) { | ||||||
|  | 				return new Promise(resolve => setTimeout(resolve, ms)); | ||||||
|  | 			} | ||||||
|  | 			function download(filename, text) { | ||||||
|  | 				var element = document.createElement('a'); | ||||||
|  | 				element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); | ||||||
|  | 				element.setAttribute('download', filename); | ||||||
|  | 				element.style.display = 'none'; | ||||||
|  | 				document.body.appendChild(element); | ||||||
|  | 				element.click(); | ||||||
|  | 				document.body.removeChild(element); | ||||||
|  | 			} | ||||||
|  | 			function openSocket() { | ||||||
|  | 				if (ws) { | ||||||
|  | 					return false; | ||||||
|  | 				} | ||||||
|  | 				ws = new WebSocket("{{.}}"); | ||||||
|  | 				ws.onclose = async function(evt) { | ||||||
|  | 					ws = null; | ||||||
|  | 					while(ws == null){ | ||||||
|  | 						openSocket() | ||||||
|  | 						await sleep(5000); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				ws.onmessage = function(evt) { | ||||||
|  | 					var entry = JSON.parse(evt.data) | ||||||
|  | 					logs.push(entry) | ||||||
|  | 					var row = document.createElement('tr'); | ||||||
|  | 					var ts = document.createElement('td'); | ||||||
|  | 					var tst = document.createTextNode(entry.timestamp); | ||||||
|  | 					ts.appendChild(tst); | ||||||
|  | 					row.appendChild(ts); | ||||||
|  | 					var ts = document.createElement('td'); | ||||||
|  | 					var tst = document.createTextNode(entry.level); | ||||||
|  | 					ts.appendChild(tst); | ||||||
|  | 					row.appendChild(ts); | ||||||
|  | 					var ts = document.createElement('td'); | ||||||
|  | 					var tst = document.createTextNode(entry.output); | ||||||
|  | 					ts.appendChild(tst); | ||||||
|  | 					row.appendChild(ts); | ||||||
|  | 					var ts = document.createElement('td'); | ||||||
|  | 					var tst = document.createTextNode(entry.file); | ||||||
|  | 					ts.appendChild(tst); | ||||||
|  | 					row.appendChild(ts); | ||||||
|  | 					var bg=""; | ||||||
|  | 					switch(entry.level){ | ||||||
|  | 						case "INFO": | ||||||
|  | 							bg="white"; | ||||||
|  | 							break; | ||||||
|  | 						case "ERROR": | ||||||
|  | 							bg="#f44336"; | ||||||
|  | 							break; | ||||||
|  | 						case "WARN": | ||||||
|  | 							bg="#fb8c00" | ||||||
|  | 							break; | ||||||
|  | 						case "TRACE": | ||||||
|  | 							bg="#E1F5FE" | ||||||
|  | 							break; | ||||||
|  | 						case "DEBUG": | ||||||
|  | 							bg="#B3E5FC" | ||||||
|  | 							break; | ||||||
|  | 						default: | ||||||
|  | 							bg="white" | ||||||
|  | 							break; | ||||||
|  | 					} | ||||||
|  | 					row.style.backgroundColor=bg | ||||||
|  | 					logTableB.append(row) | ||||||
|  | 					filterTable() | ||||||
|  | 				} | ||||||
|  | 				ws.onerror = function(evt) { | ||||||
|  | 					if (evt != null && evt.data != null){ | ||||||
|  | 						// handle error here | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			function clearTable(){ | ||||||
|  | 				if(!window.confirm("Are you sure you want to delete all logs?")){ | ||||||
|  | 					return | ||||||
|  | 				} | ||||||
|  | 				logs = [] | ||||||
|  | 
 | ||||||
|  | 				while (logTableB.childNodes.length > 1) { | ||||||
|  | 					logTableB.removeChild(logTableB.childNodes[1]); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			function filterTable() { | ||||||
|  | 				var cols, input, filter, table, tr, td, i, txtValue, w; | ||||||
|  | 				input = document.getElementById("search"); | ||||||
|  | 				filter = input.value; | ||||||
|  | 				table = logTableB; | ||||||
|  | 				tr = table.getElementsByTagName("tr"); | ||||||
|  | 				for (i = 1; i < tr.length; i++) { | ||||||
|  | 					cols = tr[i].getElementsByTagName("td"); | ||||||
|  | 					var visible = false; | ||||||
|  | 					for (w = 0; w < cols.length; w++){ | ||||||
|  | 						if (!visible && cols[w]) { | ||||||
|  | 							td = cols[w] | ||||||
|  | 							txtValue = td.textContent || td.innerText; | ||||||
|  | 							if (txtValue.indexOf(filter) > -1) { | ||||||
|  | 								visible = true | ||||||
|  | 							}  | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					if(visible){ | ||||||
|  | 
 | ||||||
|  | 						tr[i].style.display = ""; | ||||||
|  | 					} else { | ||||||
|  | 
 | ||||||
|  | 						tr[i].style.display = "none"; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			function pageScroll() { | ||||||
|  | 				if (document.getElementById('shouldScroll').checked) { | ||||||
|  | 					document.getElementById('tableWrapper').scrollBy(0,10); | ||||||
|  | 
 | ||||||
|  | 				} | ||||||
|  | 				setTimeout(pageScroll,10); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			document.getElementById("delete").addEventListener("click", function(){ | ||||||
|  | 
 | ||||||
|  | 				clearTable() | ||||||
|  | 			}, false); | ||||||
|  | 			document.getElementById("download").addEventListener("click", function(){ | ||||||
|  | 
 | ||||||
|  | 				download(application+'.json',JSON.stringify(logs)); | ||||||
|  | 			}, false); | ||||||
|  | 			openSocket(); | ||||||
|  | 			pageScroll(); | ||||||
|  | 		</script> | ||||||
|  | 
 | ||||||
|  | 	</footer> | ||||||
|  | </html> | ||||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | |||||||
| module github.com/taigrr/log-socket | module github.com/taigrr/log-socket | ||||||
| 
 | 
 | ||||||
| go 1.17 | go 1.21 | ||||||
| 
 | 
 | ||||||
| require github.com/gorilla/websocket v1.4.2 | require github.com/gorilla/websocket v1.5.0 | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							| @ -1,2 +1,2 @@ | |||||||
| github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= | github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= | ||||||
| github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||||||
|  | |||||||
							
								
								
									
										148
									
								
								log/log.go
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								log/log.go
									
									
									
									
									
								
							| @ -26,18 +26,12 @@ func init() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Client) logStdErr() { | func (c *Client) logStdErr() { | ||||||
| 	for { | 	for e := range c.writer { | ||||||
| 		select { | 		if e.level >= c.LogLevel { | ||||||
| 		case e, more := <-c.writer: | 			fmt.Fprintf(os.Stderr, "%s\t%s\t%s\t%s\n", e.Timestamp.String(), e.Level, e.Output, e.File) | ||||||
| 			if e.level >= c.LogLevel { |  | ||||||
| 				fmt.Fprintf(os.Stderr, "%s\t%s\t%s\t%s\n", e.Timestamp.String(), e.Level, e.Output, e.File) |  | ||||||
| 			} |  | ||||||
| 			if !more { |  | ||||||
| 				stderrFinished <- true |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	stderrFinished <- true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func CreateClient() *Client { | func CreateClient() *Client { | ||||||
| @ -61,7 +55,7 @@ func Flush() { | |||||||
| func (c *Client) Destroy() error { | func (c *Client) Destroy() error { | ||||||
| 	var otherClients []*Client | 	var otherClients []*Client | ||||||
| 	if !c.initialized { | 	if !c.initialized { | ||||||
| 		panic(errors.New("Cannot delete uninitialized client, did you use CreateClient?")) | 		panic(errors.New("cannot delete uninitialized client, did you use CreateClient?")) | ||||||
| 	} | 	} | ||||||
| 	sliceTex.Lock() | 	sliceTex.Lock() | ||||||
| 	c.writer = nil | 	c.writer = nil | ||||||
| @ -78,7 +72,7 @@ func (c *Client) Destroy() error { | |||||||
| 
 | 
 | ||||||
| func (c *Client) GetLogLevel() Level { | func (c *Client) GetLogLevel() Level { | ||||||
| 	if !c.initialized { | 	if !c.initialized { | ||||||
| 		panic(errors.New("Cannot get level for uninitialized client, use CreateClient instead")) | 		panic(errors.New("cannot get level for uninitialized client, use CreateClient instead")) | ||||||
| 	} | 	} | ||||||
| 	return c.LogLevel | 	return c.LogLevel | ||||||
| } | } | ||||||
| @ -109,14 +103,14 @@ func SetLogLevel(level Level) { | |||||||
| // SetLogLevel set log level of logger | // SetLogLevel set log level of logger | ||||||
| func (c *Client) SetLogLevel(level Level) { | func (c *Client) SetLogLevel(level Level) { | ||||||
| 	if !c.initialized { | 	if !c.initialized { | ||||||
| 		panic(errors.New("Cannot set level for uninitialized client, use CreateClient instead")) | 		panic(errors.New("cannot set level for uninitialized client, use CreateClient instead")) | ||||||
| 	} | 	} | ||||||
| 	c.LogLevel = level | 	c.LogLevel = level | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Client) Get() Entry { | func (c *Client) Get() Entry { | ||||||
| 	if !c.initialized { | 	if !c.initialized { | ||||||
| 		panic(errors.New("Cannot get logs for uninitialized client, did you use CreateClient?")) | 		panic(errors.New("cannot get logs for uninitialized client, did you use CreateClient?")) | ||||||
| 	} | 	} | ||||||
| 	return <-c.writer | 	return <-c.writer | ||||||
| } | } | ||||||
| @ -147,6 +141,19 @@ func Tracef(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Trace prints out logs on trace level with newline | ||||||
|  | func Traceln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "TRACE", | ||||||
|  | 		level:     LTrace, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Debug prints out logs on debug level | // Debug prints out logs on debug level | ||||||
| func Debug(args ...interface{}) { | func Debug(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -173,6 +180,19 @@ func Debugf(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Debug prints out logs on debug level with a newline | ||||||
|  | func Debugln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "DEBUG", | ||||||
|  | 		level:     LDebug, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Info prints out logs on info level | // Info prints out logs on info level | ||||||
| func Info(args ...interface{}) { | func Info(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -199,6 +219,19 @@ func Infof(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Info prints out logs on info level with a newline | ||||||
|  | func Infoln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "INFO", | ||||||
|  | 		level:     LInfo, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Info prints out logs on info level | // Info prints out logs on info level | ||||||
| func Notice(args ...interface{}) { | func Notice(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -225,6 +258,19 @@ func Noticef(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Info prints out logs on info level with a newline | ||||||
|  | func Noticeln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "NOTICE", | ||||||
|  | 		level:     LNotice, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Warn prints out logs on warn level | // Warn prints out logs on warn level | ||||||
| func Warn(args ...interface{}) { | func Warn(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -251,6 +297,19 @@ func Warnf(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Newline print for Warn | ||||||
|  | func Warnln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "WARN", | ||||||
|  | 		level:     LWarn, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Error prints out logs on error level | // Error prints out logs on error level | ||||||
| func Error(args ...interface{}) { | func Error(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -277,6 +336,19 @@ func Errorf(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Error prints out logs on error level with a newline | ||||||
|  | func Errorln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "ERROR", | ||||||
|  | 		level:     LError, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Panic prints out logs on panic level | // Panic prints out logs on panic level | ||||||
| func Panic(args ...interface{}) { | func Panic(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -323,6 +395,28 @@ func Panicf(format string, args ...interface{}) { | |||||||
| 	panic(errors.New(output)) | 	panic(errors.New(output)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func Panicln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "PANIC", | ||||||
|  | 		level:     LPanic, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | 	if len(args) >= 0 { | ||||||
|  | 		switch args[0].(type) { | ||||||
|  | 		case error: | ||||||
|  | 			panic(args[0]) | ||||||
|  | 		default: | ||||||
|  | 			// falls through to default below | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	Flush() | ||||||
|  | 	panic(errors.New(output)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Fatal prints out logs on fatal level | // Fatal prints out logs on fatal level | ||||||
| func Fatal(args ...interface{}) { | func Fatal(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -353,6 +447,32 @@ func Fatalf(format string, args ...interface{}) { | |||||||
| 	os.Exit(1) | 	os.Exit(1) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func Fatalln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(2), | ||||||
|  | 		Level:     "FATAL", | ||||||
|  | 		level:     LFatal, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | 	Flush() | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Print(args ...interface{}) { | ||||||
|  | 	Info(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Printf(format string, args ...interface{}) { | ||||||
|  | 	Infof(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Println(args ...interface{}) { | ||||||
|  | 	Infoln(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // fileInfo for getting which line in which file | // fileInfo for getting which line in which file | ||||||
| func fileInfo(skip int) string { | func fileInfo(skip int) string { | ||||||
| 	_, file, line, ok := runtime.Caller(skip) | 	_, file, line, ok := runtime.Caller(skip) | ||||||
|  | |||||||
| @ -55,8 +55,7 @@ func BenchmarkDebugSerial(b *testing.B) { | |||||||
| // Trace ensure logs come out in the right order | // Trace ensure logs come out in the right order | ||||||
| func TestOrder(t *testing.T) { | func TestOrder(t *testing.T) { | ||||||
| 	testString := "Testing trace: " | 	testString := "Testing trace: " | ||||||
| 	var c *Client | 	c := CreateClient() | ||||||
| 	c = CreateClient() |  | ||||||
| 	c.SetLogLevel(LTrace) | 	c.SetLogLevel(LTrace) | ||||||
| 
 | 
 | ||||||
| 	for i := 0; i < 5000; i++ { | 	for i := 0; i < 5000; i++ { | ||||||
| @ -86,6 +85,15 @@ func TestInfo(t *testing.T) { | |||||||
| 	//	} | 	//	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Print prints out logs on info level | ||||||
|  | func TestPrint(t *testing.T) { | ||||||
|  | 	//	if logLevel >= LInfo { | ||||||
|  | 	//		entry := logger.WithFields(logrus.Fields{}) | ||||||
|  | 	//		entry.Data["file"] = fileInfo(2) | ||||||
|  | 	//		entry.Info(args...) | ||||||
|  | 	//	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Warn prints out logs on warn level | // Warn prints out logs on warn level | ||||||
| func TestWarn(t *testing.T) { | func TestWarn(t *testing.T) { | ||||||
| 	//	if logLevel >= LWarn { | 	//	if logLevel >= LWarn { | ||||||
| @ -121,6 +129,7 @@ func TestPanic(t *testing.T) { | |||||||
| 	//		entry.Panic(args...) | 	//		entry.Panic(args...) | ||||||
| 	//	} | 	//	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
| func TestFlush(t *testing.T) { | func TestFlush(t *testing.T) { | ||||||
| 	defer Flush() | 	defer Flush() | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										128
									
								
								log/logger.go
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								log/logger.go
									
									
									
									
									
								
							| @ -7,7 +7,11 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func (l Logger) SetInfoDepth(depth int) { | func Default() *Logger { | ||||||
|  | 	return &Logger{FileInfoDepth: 0} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (l *Logger) SetInfoDepth(depth int) { | ||||||
| 	l.FileInfoDepth = depth | 	l.FileInfoDepth = depth | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -37,6 +41,19 @@ func (l Logger) Tracef(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Trace prints out logs on trace level with newline | ||||||
|  | func (l Logger) Traceln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(l.FileInfoDepth), | ||||||
|  | 		Level:     "TRACE", | ||||||
|  | 		level:     LTrace, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Debug prints out logs on debug level | // Debug prints out logs on debug level | ||||||
| func (l Logger) Debug(args ...interface{}) { | func (l Logger) Debug(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -89,7 +106,20 @@ func (l Logger) Infof(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Info prints out logs on info level | // Info prints out logs on info level with newline | ||||||
|  | func (l Logger) Infoln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(l.FileInfoDepth), | ||||||
|  | 		Level:     "INFO", | ||||||
|  | 		level:     LInfo, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Notice prints out logs on notice level | ||||||
| func (l Logger) Notice(args ...interface{}) { | func (l Logger) Notice(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| 	e := Entry{ | 	e := Entry{ | ||||||
| @ -102,7 +132,7 @@ func (l Logger) Notice(args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Formatted print for Info | // Formatted print for Notice | ||||||
| func (l Logger) Noticef(format string, args ...interface{}) { | func (l Logger) Noticef(format string, args ...interface{}) { | ||||||
| 	output := fmt.Sprintf(format, args...) | 	output := fmt.Sprintf(format, args...) | ||||||
| 	e := Entry{ | 	e := Entry{ | ||||||
| @ -115,6 +145,19 @@ func (l Logger) Noticef(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Notice prints out logs on notice level with newline | ||||||
|  | func (l Logger) Noticeln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(l.FileInfoDepth), | ||||||
|  | 		Level:     "NOTICE", | ||||||
|  | 		level:     LNotice, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Warn prints out logs on warn level | // Warn prints out logs on warn level | ||||||
| func (l Logger) Warn(args ...interface{}) { | func (l Logger) Warn(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -141,6 +184,19 @@ func (l Logger) Warnf(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Warn prints out logs on warn level with a newline | ||||||
|  | func (l Logger) Warnln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(l.FileInfoDepth), | ||||||
|  | 		Level:     "WARN", | ||||||
|  | 		level:     LWarn, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Error prints out logs on error level | // Error prints out logs on error level | ||||||
| func (l Logger) Error(args ...interface{}) { | func (l Logger) Error(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -167,6 +223,19 @@ func (l Logger) Errorf(format string, args ...interface{}) { | |||||||
| 	createLog(e) | 	createLog(e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Error prints out logs on error level with a new line | ||||||
|  | func (l Logger) Errorln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(l.FileInfoDepth), | ||||||
|  | 		Level:     "ERROR", | ||||||
|  | 		level:     LError, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Panic prints out logs on panic level | // Panic prints out logs on panic level | ||||||
| func (l Logger) Panic(args ...interface{}) { | func (l Logger) Panic(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -213,6 +282,29 @@ func (l Logger) Panicf(format string, args ...interface{}) { | |||||||
| 	panic(errors.New(output)) | 	panic(errors.New(output)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Panic prints out logs on panic level with a newline | ||||||
|  | func (l Logger) Panicln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(l.FileInfoDepth), | ||||||
|  | 		Level:     "PANIC", | ||||||
|  | 		level:     LPanic, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | 	if len(args) >= 0 { | ||||||
|  | 		switch args[0].(type) { | ||||||
|  | 		case error: | ||||||
|  | 			panic(args[0]) | ||||||
|  | 		default: | ||||||
|  | 			// falls through to default below | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	Flush() | ||||||
|  | 	panic(errors.New(output)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Fatal prints out logs on fatal level | // Fatal prints out logs on fatal level | ||||||
| func (l Logger) Fatal(args ...interface{}) { | func (l Logger) Fatal(args ...interface{}) { | ||||||
| 	output := fmt.Sprint(args...) | 	output := fmt.Sprint(args...) | ||||||
| @ -242,3 +334,33 @@ func (l Logger) Fatalf(format string, args ...interface{}) { | |||||||
| 	Flush() | 	Flush() | ||||||
| 	os.Exit(1) | 	os.Exit(1) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // Fatal prints fatal level with a new line | ||||||
|  | func (l Logger) Fatalln(args ...interface{}) { | ||||||
|  | 	output := fmt.Sprintln(args...) | ||||||
|  | 	e := Entry{ | ||||||
|  | 		Timestamp: time.Now(), | ||||||
|  | 		Output:    output, | ||||||
|  | 		File:      fileInfo(l.FileInfoDepth), | ||||||
|  | 		Level:     "FATAL", | ||||||
|  | 		level:     LFatal, | ||||||
|  | 	} | ||||||
|  | 	createLog(e) | ||||||
|  | 	Flush() | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Handles print to info | ||||||
|  | func (l Logger) Print(args ...interface{}) { | ||||||
|  | 	l.Info(args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Handles formatted print to info | ||||||
|  | func (l Logger) Printf(format string, args ...interface{}) { | ||||||
|  | 	l.Infof(format, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Handles print to info with new line | ||||||
|  | func (l Logger) Println(args ...interface{}) { | ||||||
|  | 	l.Infoln(args...) | ||||||
|  | } | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ func LogSocketHandler(w http.ResponseWriter, r *http.Request) { | |||||||
| 	logger.Info("Websocket client attached.") | 	logger.Info("Websocket client attached.") | ||||||
| 	for { | 	for { | ||||||
| 		logEvent := lc.Get() | 		logEvent := lc.Get() | ||||||
| 		logJSON, err := json.Marshal(logEvent) | 		logJSON, _ := json.Marshal(logEvent) | ||||||
| 		err = c.WriteMessage(websocket.TextMessage, logJSON) | 		err = c.WriteMessage(websocket.TextMessage, logJSON) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			logger.Error("write:", err) | 			logger.Error("write:", err) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user