11import { Command } from "@cliffy/command" ;
22import { publish } from "./publish.ts" ;
3- import { red } from "@std/fmt/colors" ;
3+ import { red , yellow } from "@std/fmt/colors" ;
44import { create } from "./create.ts" ;
5- import { withApp } from "./util.ts" ;
5+ import { error , renderTemporalTimestamp , withApp } from "./util.ts" ;
66import { setupAws , setupGcp } from "./setup-cloud.ts" ;
77import { getAppFromConfig , readConfig , writeConfig } from "./config.ts" ;
88import {
@@ -12,6 +12,7 @@ import {
1212 envUpdateContextsCommand ,
1313 envUpdateValueCommand ,
1414} from "./env.ts" ;
15+ import { createTrpcClient } from "./auth.ts" ;
1516
1617const createCommand = new Command < { endpoint : string } > ( )
1718 . description ( "Create a new application" )
@@ -97,6 +98,75 @@ const envCommand = new Command<{ endpoint: string }>()
9798 . command ( "update-contexts" , envUpdateContextsCommand )
9899 . command ( "delete" , envDeleteCommand ) ;
99100
101+ const logsCommand = new Command < { endpoint : string } > ( )
102+ . option ( "--org <name:string>" , "The name of the organization" )
103+ . option ( "--app <name:string>" , "The name of the application" )
104+ . option ( "--start <date:string>" , "The starting timestamp of the logs" )
105+ . option ( "--end <date:string>" , "The ending timestamp of the logs" , {
106+ depends : [ "start" ] ,
107+ } )
108+ . action ( async ( options , rootPath = Deno . cwd ( ) ) => {
109+ const configContent = await readConfig ( rootPath ) ;
110+ let { org, app } = getAppFromConfig ( configContent ) ;
111+ org ??= options . org ;
112+ app ??= options . app ;
113+ const gottenApp = await withApp ( options . endpoint , false , org , app ) ;
114+
115+ interface LogEntry {
116+ Timestamp : string ;
117+ TraceId : string ;
118+ SpanId : string ;
119+ SeverityText : string ;
120+ SeverityNumber : number ;
121+ Body : string ;
122+ ScopeName : string ;
123+ ScopeVersion : string ;
124+ LogAttributes : Record < string , string > ;
125+ Revision : string ;
126+ }
127+
128+ const trpcClient = createTrpcClient ( options . endpoint ) ;
129+
130+ const sub = ( trpcClient . apps as any ) . logs . subscribe ( {
131+ org : gottenApp . org ,
132+ app : gottenApp . app ,
133+ start : ( options . start ? new Date ( options . start ) : new Date ( ) )
134+ . toISOString ( ) ,
135+ end : options . end ? new Date ( options . end ) . toISOString ( ) : undefined ,
136+ filter : { } ,
137+ } , {
138+ onData : ( data : "streaming" | null | LogEntry [ ] ) => {
139+ if ( data === "streaming" ) {
140+ console . log ( "Streaming logs..." ) ;
141+ } else if ( Array . isArray ( data ) ) {
142+ for ( const log of data ) {
143+ let text = `[${ renderTemporalTimestamp ( log . Timestamp ) } ${
144+ log . TraceId ? ` (${ log . TraceId } )` : ""
145+ } ] ${ log . Body } `;
146+ if ( text . endsWith ( "\n" ) ) {
147+ text = text . slice ( 0 , - 1 ) ;
148+ }
149+
150+ if ( log . SeverityNumber >= 17 ) {
151+ console . log ( red ( text ) ) ;
152+ } else if ( log . SeverityNumber >= 13 ) {
153+ console . log ( yellow ( text ) ) ;
154+ } else {
155+ console . log ( text ) ;
156+ }
157+ }
158+ }
159+ } ,
160+ onError : ( err : unknown ) => {
161+ sub . unsubscribe ( ) ;
162+ error ( Deno . inspect ( err ) ) ;
163+ } ,
164+ onStopped : ( ) => {
165+ sub . unsubscribe ( ) ;
166+ } ,
167+ } ) ;
168+ } ) ;
169+
100170await new Command ( )
101171 . name ( "deno deploy" )
102172 . description ( `Interact with Deno Deploy
@@ -149,6 +219,7 @@ deploy your local directory to the specified application.`)
149219 )
150220 . command ( "create" , createCommand )
151221 . command ( "env" , envCommand )
222+ . command ( "logs" , logsCommand )
152223 . command ( "setup-aws" , setupAWSCommand )
153224 . command ( "setup-gcp" , setupGCPCommand )
154225 . command ( "tunnel-login" , tunnelLoginCommand )
0 commit comments