12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
15
- """Client for interacting with the Stackdriver Logging API"""
15
+ """Client for interacting with the Stackdriver Error Reporting API"""
16
16
17
+ import os
17
18
import traceback
18
19
19
- import google .cloud .logging .client
20
+ try :
21
+ from google .cloud .error_reporting ._gax import make_report_error_api
22
+ except ImportError : # pragma: NO COVER
23
+ _HAVE_GAX = False
24
+ else :
25
+ _HAVE_GAX = True
26
+
27
+ from google .cloud ._helpers import _determine_default_project
28
+ from google .cloud .error_reporting ._logging import _ErrorReportingLoggingAPI
29
+ from google .cloud .environment_vars import DISABLE_GRPC
30
+
20
31
import six
21
32
33
+ _DISABLE_GAX = os .getenv (DISABLE_GRPC , False )
34
+ _USE_GAX = _HAVE_GAX and not _DISABLE_GAX
35
+
22
36
23
37
class HTTPContext (object ):
24
38
"""HTTPContext defines an object that captures the parameter for the
@@ -96,6 +110,12 @@ class Client(object):
96
110
SHA-1 hash, for example. If the developer did not provide
97
111
a version, the value is set to default.
98
112
113
+ :type use_gax: bool
114
+ :param use_gax: (Optional) Explicitly specifies whether
115
+ to use the gRPC transport (via GAX) or HTTP. If unset,
116
+ falls back to the ``GOOGLE_CLOUD_DISABLE_GRPC`` environment
117
+ variable.
118
+
99
119
:raises: :class:`ValueError` if the project is neither passed in nor
100
120
set in the environment.
101
121
"""
@@ -104,24 +124,48 @@ def __init__(self, project=None,
104
124
credentials = None ,
105
125
http = None ,
106
126
service = None ,
107
- version = None ):
108
- self .logging_client = google .cloud .logging .client .Client (
109
- project , credentials , http )
127
+ version = None ,
128
+ use_gax = None ):
129
+ if project is None :
130
+ self ._project = _determine_default_project ()
131
+ else :
132
+ self ._project = project
133
+ self ._credentials = credentials
134
+ self ._http = http
135
+
136
+ self ._report_errors_api = None
137
+
110
138
self .service = service if service else self .DEFAULT_SERVICE
111
139
self .version = version
140
+ if use_gax is None :
141
+ self ._use_gax = _USE_GAX
142
+ else :
143
+ self ._use_gax = use_gax
112
144
113
145
DEFAULT_SERVICE = 'python'
114
146
115
- def _send_error_report (self , message ,
116
- report_location = None , http_context = None , user = None ):
117
- """Makes the call to the Error Reporting API via the log stream.
147
+ @property
148
+ def report_errors_api (self ):
149
+ """Helper for logging-related API calls.
150
+
151
+ See:
152
+ https://cloud.google.com/logging/docs/api/reference/rest/v2/entries
153
+ https://cloud.google.com/logging/docs/api/reference/rest/v2/projects.logs
154
+ """
155
+ if self ._report_errors_api is None :
156
+ if self ._use_gax :
157
+ self ._report_errors_api = make_report_error_api (self ._project )
158
+ else :
159
+ self ._report_errors_api = _ErrorReportingLoggingAPI (
160
+ self ._project , self ._credentials , self ._http )
161
+ return self ._report_errors_api
118
162
119
- This is the lower-level interface to build the payload, generally
120
- users will use either report() or report_exception() to automatically
121
- gather the parameters for this method.
122
163
123
- Currently this method sends the Error Report by formatting a structured
124
- log message according to
164
+ def _build_error_report (self , message ,
165
+ report_location = None , http_context = None , user = None ):
166
+ """Builds the Error Reporting object to report.
167
+
168
+ This builds the object according to
125
169
126
170
https://cloud.google.com/error-reporting/docs/formatting-error-messages
127
171
@@ -151,7 +195,7 @@ def _send_error_report(self, message,
151
195
logged in. In this case the Error Reporting system will
152
196
use other data, such as remote IP address,
153
197
to distinguish affected users.
154
- """
198
+ """
155
199
payload = {
156
200
'serviceContext' : {
157
201
'service' : self .service ,
@@ -174,13 +218,50 @@ def _send_error_report(self, message,
174
218
payload ['context' ]['httpContext' ] = {
175
219
key : value for key , value in six .iteritems (http_context_dict )
176
220
if value is not None
177
- }
221
+ }
178
222
179
223
if user :
180
224
payload ['context' ]['user' ] = user
225
+ return payload
181
226
182
- logger = self .logging_client .logger ('errors' )
183
- logger .log_struct (payload )
227
+ def _send_error_report (self , message ,
228
+ report_location = None , http_context = None , user = None ):
229
+ """Makes the call to the Error Reporting API.
230
+
231
+ This is the lower-level interface to build and send the payload,
232
+ generally users will use either report() or report_exception() to
233
+ automatically gather the parameters for this method.
234
+
235
+ :type message: str
236
+ :param message: The stack trace that was reported or logged by the
237
+ service.
238
+
239
+ :type report_location: dict
240
+ :param report_location: The location in the source code where the
241
+ decision was made to report the error, usually the place
242
+ where it was logged. For a logged exception this would be the
243
+ source line where the exception is logged, usually close to
244
+ the place where it was caught.
245
+
246
+ This should be a Python dict that contains the keys 'filePath',
247
+ 'lineNumber', and 'functionName'
248
+
249
+ :type http_context: :class`google.cloud.error_reporting.HTTPContext`
250
+ :param http_context: The HTTP request which was processed when the
251
+ error was triggered.
252
+
253
+ :type user: str
254
+ :param user: The user who caused or was affected by the crash. This can
255
+ be a user ID, an email address, or an arbitrary token that
256
+ uniquely identifies the user. When sending an error
257
+ report, leave this field empty if the user was not
258
+ logged in. In this case the Error Reporting system will
259
+ use other data, such as remote IP address,
260
+ to distinguish affected users.
261
+ """
262
+ error_report = self ._build_error_report (message , report_location ,
263
+ http_context , user )
264
+ self .report_errors_api .report_error_event (error_report )
184
265
185
266
def report (self , message , http_context = None , user = None ):
186
267
""" Reports a message to Stackdriver Error Reporting
0 commit comments