@@ -24,7 +24,7 @@ import {Response} from 'teeny-request';
2424import { google } from '../proto/logging' ;
2525
2626import { GetEntriesCallback , GetEntriesResponse , Logging } from '.' ;
27- import { Entry , LogEntry } from './entry' ;
27+ import { Entry , EntryJson , LogEntry } from './entry' ;
2828import { getDefaultResource } from './metadata' ;
2929
3030const snakeCaseKeys = require ( 'snakecase-keys' ) ;
@@ -44,6 +44,7 @@ export interface GetEntriesRequest {
4444
4545export interface LogOptions {
4646 removeCircular ?: boolean ;
47+ maxEntrySize ?: number ; // see: https://cloud.google.com/logging/quotas
4748}
4849
4950export type ApiResponse = [ Response ] ;
@@ -103,12 +104,14 @@ type LogSeverityFunctions = {
103104class Log implements LogSeverityFunctions {
104105 formattedName_ : string ;
105106 removeCircular_ : boolean ;
107+ maxEntrySize ?: number ;
106108 logging : Logging ;
107109 name : string ;
108110 constructor ( logging : Logging , name : string , options ?: LogOptions ) {
109111 options = options || { } ;
110112 this . formattedName_ = Log . formatName_ ( logging . projectId , name ) ;
111113 this . removeCircular_ = options . removeCircular === true ;
114+ this . maxEntrySize = options . maxEntrySize ;
112115 this . logging = logging ;
113116 /**
114117 * @name Log#name
@@ -828,6 +831,7 @@ class Log implements LogSeverityFunctions {
828831 } catch ( err ) {
829832 // Ignore errors (the API will speak up if it has an issue).
830833 }
834+ self . truncateEntries ( decoratedEntries ) ;
831835 const projectId = await self . logging . auth . getProjectId ( ) ;
832836 self . formattedName_ = Log . formatName_ ( projectId , self . name ) ;
833837 const reqOpts = extend (
@@ -855,7 +859,7 @@ class Log implements LogSeverityFunctions {
855859 * @returns {object[] } Serialized entries.
856860 * @throws if there is an error during serialization.
857861 */
858- decorateEntries_ ( entries : Entry [ ] ) {
862+ decorateEntries_ ( entries : Entry [ ] ) : EntryJson [ ] {
859863 return entries . map ( entry => {
860864 if ( ! ( entry instanceof Entry ) ) {
861865 entry = this . entry ( entry ) ;
@@ -866,6 +870,48 @@ class Log implements LogSeverityFunctions {
866870 } ) ;
867871 }
868872
873+ /**
874+ * Truncate log entries at maxEntrySize, so that error is not thrown, see:
875+ * https://cloud.google.com/logging/quotas
876+ *
877+ * @private
878+ *
879+ * @param {object|string } the JSON log entry.
880+ * @returns {object|string } truncated JSON log entry.
881+ */
882+ private truncateEntries ( entries : EntryJson [ ] ) {
883+ return entries . forEach ( entry => {
884+ if ( this . maxEntrySize === undefined ) return ;
885+
886+ const payloadSize = JSON . stringify ( entry ) . length ;
887+ if ( payloadSize < this . maxEntrySize ) return ;
888+
889+ const delta = payloadSize - this . maxEntrySize ;
890+ if ( entry . textPayload ) {
891+ entry . textPayload = entry . textPayload . slice (
892+ 0 ,
893+ Math . max ( entry . textPayload . length - delta , 0 )
894+ ) ;
895+ } else {
896+ // Stackdriver Log Viewer picks up the summary line from the
897+ // 'message' field.
898+ if (
899+ entry . jsonPayload &&
900+ entry . jsonPayload . fields &&
901+ entry . jsonPayload . fields . message &&
902+ entry . jsonPayload . fields . message . stringValue
903+ ) {
904+ const text : string | null | undefined =
905+ entry . jsonPayload . fields . message . stringValue ;
906+ entry . jsonPayload . fields . message . stringValue = text . slice (
907+ 0 ,
908+ Math . max ( text . length - delta , 0 )
909+ ) ;
910+ }
911+ }
912+ } ) ;
913+ }
914+
869915 /**
870916 * Return an array of log entries with the desired severity assigned.
871917 *
0 commit comments