UNPKG

3.9 kBJavaScriptView Raw
1var AWS = require( "aws-sdk" );
2const fs = require( "fs" );
3const _ = require( "lodash" );
4const chalk = require( "chalk" );
5const moment = require( "moment" );
6var os = require( "os");
7
8const utils = require( "./utils" );
9
10const projectConfig = utils.getProjectConfig();
11
12AWS.config.region = projectConfig.region;
13
14function getLogName() {
15
16 if ( process.env.COLLY__LAMBDA_NAME ) {
17 return `/aws/lambda/${utils.getLambdaName()}`;
18 }
19
20 throw new Error("Unable to determine which log group name to use.");
21}
22
23function getLogs() {
24
25 return new Promise( ( resolve, reject ) => {
26
27 const cloudwatchlogs = new AWS.CloudWatchLogs();
28
29 const params = {
30 "logGroupName": getLogName(),
31 "descending": true,
32 "limit": 50,
33 "orderBy": "LastEventTime"
34 };
35
36 cloudwatchlogs.describeLogStreams( params, function( err, data ) {
37
38 if ( err ) {
39
40 reject( err );
41
42 } else {
43
44 if ( data.logStreams.length === 0 ) {
45 reject( "No logs exist yet." );
46 }
47
48 resolve(
49 _.chain( data.logStreams )
50 // .filter( stream => stream.logStreamName.includes( "[$LATEST]" ) )
51 .map( "logStreamName" )
52 .value()
53 );
54
55 }
56
57 });
58
59 });
60
61}
62
63function formatLogEvent( msg ) {
64
65 const dateFormat = "YYYY-MM-DD HH:mm:ss.SSS (Z)";
66
67 if ( msg.startsWith( "REPORT" ) ) {
68 msg += os.EOL;
69 }
70
71 if ( msg.startsWith( "START" ) || msg.startsWith( "END" ) || msg.startsWith( "REPORT" ) ) {
72
73 return chalk.gray( msg );
74
75 } else if ( msg.trim() === "Process exited before completing request" ) {
76
77 return chalk.red(msg);
78
79 }
80
81 const splitted = msg.split( "\t" );
82
83 if ( splitted.length < 3 || new Date( splitted[ 0 ] ) === "Invalid Date" ) {
84 return msg;
85 }
86
87 const reqId = splitted[ 1 ];
88 const time = chalk.green( moment( splitted[ 0 ] ).format( dateFormat ) );
89 const text = msg.split( `${reqId}\t` )[ 1 ];
90
91 return `${time}\t${chalk.yellow(reqId)}\t${text}\n\n`;
92
93};
94
95let startTime;
96
97function showLogs( logStreamNames ) {
98
99 return new Promise( ( resolve, reject ) => {
100
101 console.log( "Requesting logs..." );
102
103 console.log( "logStreamNames.length: " + logStreamNames.length );
104
105 const cloudwatchlogs = new AWS.CloudWatchLogs();
106
107 const params = {
108 "logGroupName": getLogName(),
109 "interleaved": true,
110 "logStreamNames": logStreamNames
111 };
112
113 if ( process.env.COLLY__SEARCH ) {
114 params.filterPattern = process.env.COLLY__SEARCH;
115 }
116
117 if ( process.env.COLLY__START_TIME ) {
118
119 startTime = process.env.COLLY__START_TIME;
120
121 const since = ( [ "m", "h", "d" ].indexOf( startTime[ startTime.length - 1 ] ) !== -1 );
122
123 if ( since ) {
124
125 params.startTime = moment().subtract(
126 startTime.replace( /\D/g, ""),
127 startTime.replace( /\d/g, "")
128 ).valueOf();
129
130 } else {
131
132 params.startTime = moment.utc( startTime ).valueOf();
133
134 }
135
136 }
137
138 cloudwatchlogs.filterLogEvents( params, function( err, data ) {
139
140 if ( err ) {
141 reject( err );
142 return;
143 }
144 if ( data.events ) {
145 data.events.forEach( ( e ) => {
146
147 process.stdout.write( formatLogEvent( e.message ) );
148
149 });
150 }
151
152 // If we tail the logs then we need to set the
153 // start time from the last possible event
154 if ( process.env.COLLY__TAIL && ( data.events.length > 0) ) {
155
156 startTime = data.events.pop().timestamp + 1;
157
158 }
159
160 // If we are tailing the logs, or there is another
161 // page of logs then recurse back into the function
162 const tail = JSON.parse( process.env.COLLY__TAIL );
163 if ( tail || data.nextToken ) {
164 setTimeout( () => {
165 showLogs( logStreamNames, ( data.nextToken || null ) );
166 }, 1000);
167 }
168
169 resolve();
170
171 });
172
173 });
174
175}
176
177function init () {
178 utils.authenticate()
179 .then( getLogs )
180 .then( showLogs )
181 .catch( console.log );
182}
183
184module.exports = {
185 "init": init
186}
\No newline at end of file