66
77namespace notamedia \sentry ;
88
9+ use Sentry \Severity ;
10+ use Sentry \State \Scope ;
11+ use Throwable ;
12+ use Yii ;
913use yii \helpers \ArrayHelper ;
1014use yii \log \Logger ;
1115use yii \log \Target ;
16+ use yii \web \Request ;
17+ use yii \web \User ;
1218
1319/**
1420 * SentryTarget records log messages in a Sentry.
@@ -33,19 +39,15 @@ class SentryTarget extends Target
3339 * @var callable Callback function that can modify extra's array
3440 */
3541 public $ extraCallback ;
36- /**
37- * @var \Sentry
38- */
39- protected $ client ;
4042
4143 /**
42- * @inheritdoc
44+ * @inheritDoc
4345 */
44- public function collect ( $ messages , $ final )
46+ public function __construct ( $ config = [] )
4547 {
46- \ Sentry \init ( array_merge ([ ' dsn ' => $ this -> dsn ], $ this -> clientOptions ) );
48+ parent :: __construct ( $ config );
4749
48- parent :: collect ( $ messages , $ final );
50+ \ Sentry \init ( array_merge ([ ' dsn ' => $ this -> dsn ] , $ this -> clientOptions ) );
4951 }
5052
5153 /**
@@ -62,69 +64,82 @@ protected function getContextMessage()
6264 public function export ()
6365 {
6466 foreach ($ this ->messages as $ message ) {
65- list ( $ text , $ level , $ category, $ timestamp , $ traces ) = $ message ;
67+ [ $ text , $ level , $ category] = $ message ;
6668
6769 $ data = [
68- 'level ' => static ::getLevelName ($ level ),
6970 'message ' => '' ,
70- 'timestamp ' => $ timestamp ,
71- 'tags ' => ['category ' => $ category ]
71+ 'tags ' => ['category ' => $ category ],
72+ 'extra ' => [],
73+ 'userData ' => [],
7274 ];
7375
74- if ($ text instanceof \Throwable || $ text instanceof \Exception) {
75- $ data = $ this ->runExtraCallback ($ text , $ data );
76- \Sentry \captureException ($ text , $ data );
77- continue ;
78- } elseif (is_array ($ text )) {
79- if (isset ($ text ['msg ' ])) {
80- $ data ['message ' ] = $ text ['msg ' ];
81- unset($ text ['msg ' ]);
82- }
76+ $ request = Yii::$ app ->getRequest ();
77+ if ($ request instanceof Request && $ request ->getUserIP ()) {
78+ $ data ['userData ' ]['ip_address ' ] = $ request ->getUserIP ();
79+ }
8380
84- if (isset ($ text ['tags ' ])) {
85- $ data ['tags ' ] = ArrayHelper::merge ($ data ['tags ' ], $ text ['tags ' ]);
86- \Sentry \configureScope (function (\Sentry \State \Scope $ scope ) use ($ data ): void {
87- foreach ($ data ['tags ' ] as $ key => $ value ) {
88- $ scope ->setTag ($ key , $ value );
89- }
90- });
91- unset($ text ['tags ' ]);
81+ try {
82+ /** @var User $user */
83+ $ user = Yii::$ app ->has ('user ' , true ) ? Yii::$ app ->get ('user ' , false ) : null ;
84+ if ($ user && ($ identity = $ user ->getIdentity (false ))) {
85+ $ data ['userData ' ]['id ' ] = $ identity ->getId ();
86+ }
87+ } catch (Throwable $ e ) {}
88+
89+ \Sentry \withScope (function (Scope $ scope ) use ($ text , $ level , $ data ) {
90+ if (is_array ($ text )) {
91+ if (isset ($ text ['msg ' ])) {
92+ $ data ['message ' ] = $ text ['msg ' ];
93+ unset($ text ['msg ' ]);
94+ }
95+
96+ if (isset ($ text ['tags ' ])) {
97+ $ data ['tags ' ] = ArrayHelper::merge ($ data ['tags ' ], $ text ['tags ' ]);
98+ unset($ text ['tags ' ]);
99+ }
100+
101+ $ data ['extra ' ] = $ text ;
102+ } else {
103+ $ data ['message ' ] = (string ) $ text ;
92104 }
93105
94- $ data ['extra ' ] = $ text ;
95-
96- if (!empty ($ data ['extra ' ])) {
97- \Sentry \configureScope (function (\Sentry \State \Scope $ scope ) use ($ data ): void {
98- foreach ($ data ['extra ' ] as $ key => $ value ) {
99- $ scope ->setExtra ((string )$ key , $ value );
100- }
101- });
106+ if ($ this ->context ) {
107+ $ data ['extra ' ]['context ' ] = parent ::getContextMessage ();
102108 }
103-
104- } else {
105- $ data ['message ' ] = $ text ;
106- }
107109
108- if ($ this ->context ) {
109- $ data ['extra ' ]['context ' ] = parent ::getContextMessage ();
110- }
110+ $ data = $ this ->runExtraCallback ($ text , $ data );
111111
112- $ data = $ this ->runExtraCallback ($ text , $ data );
113- \Sentry \captureMessage ($ data ['message ' ]);
112+ $ scope ->setUser ($ data ['userData ' ], true );
113+ foreach ($ data ['extra ' ] as $ key => $ value ) {
114+ $ scope ->setExtra ((string ) $ key , $ value );
115+ }
116+ foreach ($ data ['tags ' ] as $ key => $ value ) {
117+ if ($ value ) {
118+ $ scope ->setTag ($ key , $ value );
119+ }
120+ }
121+
122+ if ($ text instanceof Throwable) {
123+ \Sentry \captureException ($ text );
124+ } else {
125+ \Sentry \captureMessage ($ data ['message ' ], $ this ->getLogLevel ($ level ));
126+ }
127+ });
114128 }
115129 }
116130
117131 /**
118132 * Calls the extra callback if it exists
119133 *
120- * @param $text
121- * @param $data
134+ * @param mixed $text
135+ * @param array $data
136+ *
122137 * @return array
123138 */
124139 public function runExtraCallback ($ text , $ data )
125140 {
126141 if (is_callable ($ this ->extraCallback )) {
127- $ data ['extra ' ] = call_user_func ($ this ->extraCallback , $ text , isset ( $ data ['extra ' ]) ? $ data [ ' extra ' ] : []);
142+ $ data ['extra ' ] = call_user_func ($ this ->extraCallback , $ text , $ data ['extra ' ] ?? []);
128143 }
129144
130145 return $ data ;
@@ -133,7 +148,10 @@ public function runExtraCallback($text, $data)
133148 /**
134149 * Returns the text display of the specified level for the Sentry.
135150 *
136- * @param integer $level The message level, e.g. [[LEVEL_ERROR]], [[LEVEL_WARNING]].
151+ * @deprecated Deprecated from 1.5, will remove in 2.0
152+ *
153+ * @param int $level The message level, e.g. [[LEVEL_ERROR]], [[LEVEL_WARNING]].
154+ *
137155 * @return string
138156 */
139157 public static function getLevelName ($ level )
@@ -147,6 +165,31 @@ public static function getLevelName($level)
147165 Logger::LEVEL_PROFILE_END => 'debug ' ,
148166 ];
149167
150- return isset ($ levels [$ level ]) ? $ levels [$ level ] : 'error ' ;
168+ return $ levels [$ level ] ?? 'error ' ;
169+ }
170+
171+ /**
172+ * Translates Yii2 log levels to Sentry Severity.
173+ *
174+ * @param int $level
175+ *
176+ * @return Severity
177+ */
178+ protected function getLogLevel ($ level ): Severity
179+ {
180+ switch ($ level ) {
181+ case Logger::LEVEL_PROFILE :
182+ case Logger::LEVEL_PROFILE_BEGIN :
183+ case Logger::LEVEL_PROFILE_END :
184+ case Logger::LEVEL_TRACE :
185+ return Severity::debug ();
186+ case Logger::LEVEL_WARNING :
187+ return Severity::warning ();
188+ case Logger::LEVEL_ERROR :
189+ return Severity::error ();
190+ case Logger::LEVEL_INFO :
191+ default :
192+ return Severity::info ();
193+ }
151194 }
152195}
0 commit comments