@@ -1225,6 +1225,75 @@ impl<'a> AuthenticatedApi<'a> {
12251225
12261226 Ok ( rv)
12271227 }
1228+ }
1229+
1230+ /// Options for fetching organization events
1231+ #[ derive( Debug , Default ) ]
1232+ pub struct FetchEventsOptions < ' a > {
1233+ /// Project ID to filter events by
1234+ pub project_id : Option < & ' a str > ,
1235+ /// Cursor for pagination
1236+ pub cursor : Option < & ' a str > ,
1237+ /// Query string to filter events
1238+ pub query : Option < & ' a str > ,
1239+ /// Number of events per page (default: 100)
1240+ pub per_page : Option < usize > ,
1241+ /// Time period for stats (default: "1h")
1242+ pub stats_period : Option < & ' a str > ,
1243+ /// Sort order (default: "-timestamp")
1244+ pub sort : Option < & ' a str > ,
1245+ }
1246+
1247+ impl < ' a > AuthenticatedApi < ' a > {
1248+ /// Fetch organization events from the specified dataset
1249+ pub fn fetch_organization_events (
1250+ & self ,
1251+ org : & str ,
1252+ dataset : & str ,
1253+ fields : & [ & str ] ,
1254+ options : FetchEventsOptions ,
1255+ ) -> ApiResult < Vec < LogEntry > > {
1256+ let mut params = vec ! [ format!( "dataset={}" , QueryArg ( dataset) ) ] ;
1257+
1258+ for field in fields {
1259+ params. push ( format ! ( "field={}" , QueryArg ( field) ) ) ;
1260+ }
1261+
1262+ if let Some ( cursor) = options. cursor {
1263+ params. push ( format ! ( "cursor={}" , QueryArg ( cursor) ) ) ;
1264+ }
1265+
1266+ if let Some ( project_id) = options. project_id {
1267+ params. push ( format ! ( "project={}" , QueryArg ( project_id) ) ) ;
1268+ }
1269+
1270+ if let Some ( query) = options. query {
1271+ params. push ( format ! ( "query={}" , QueryArg ( query) ) ) ;
1272+ }
1273+
1274+ params. push ( format ! ( "per_page={}" , options. per_page. unwrap_or( 100 ) ) ) ;
1275+ params. push ( format ! (
1276+ "statsPeriod={}" ,
1277+ options. stats_period. unwrap_or( "1h" )
1278+ ) ) ;
1279+ params. push ( "referrer=sentry-cli-tail" . to_owned ( ) ) ;
1280+ params. push ( format ! ( "sort={}" , options. sort. unwrap_or( "-timestamp" ) ) ) ;
1281+
1282+ let url = format ! (
1283+ "/organizations/{}/events/?{}" ,
1284+ PathArg ( org) ,
1285+ params. join( "&" )
1286+ ) ;
1287+
1288+ let resp = self . get ( & url) ?;
1289+
1290+ if resp. status ( ) == 404 {
1291+ return Err ( ApiErrorKind :: OrganizationNotFound . into ( ) ) ;
1292+ }
1293+
1294+ let logs_response: LogsResponse = resp. convert ( ) ?;
1295+ Ok ( logs_response. data )
1296+ }
12281297
12291298 /// List all issues associated with an organization and a project
12301299 pub fn list_organization_project_issues (
@@ -2343,7 +2412,7 @@ pub struct ProcessedEvent {
23432412 pub tags : Option < Vec < ProcessedEventTag > > ,
23442413}
23452414
2346- #[ derive( Clone , Debug , Deserialize ) ]
2415+ #[ derive( Clone , Debug , Deserialize , Serialize ) ]
23472416pub struct ProcessedEventUser {
23482417 #[ serde( skip_serializing_if = "Option::is_none" ) ]
23492418 pub id : Option < String > ,
@@ -2377,7 +2446,7 @@ impl fmt::Display for ProcessedEventUser {
23772446 }
23782447}
23792448
2380- #[ derive( Clone , Debug , Deserialize ) ]
2449+ #[ derive( Clone , Debug , Deserialize , Serialize ) ]
23812450pub struct ProcessedEventTag {
23822451 pub key : String ,
23832452 pub value : String ,
@@ -2401,3 +2470,20 @@ pub struct Region {
24012470pub struct RegionResponse {
24022471 pub regions : Vec < Region > ,
24032472}
2473+
2474+ /// Response structure for logs API
2475+ #[ derive( Debug , Deserialize ) ]
2476+ struct LogsResponse {
2477+ data : Vec < LogEntry > ,
2478+ }
2479+
2480+ /// Log entry structure from the logs API
2481+ #[ derive( Debug , Deserialize ) ]
2482+ pub struct LogEntry {
2483+ #[ serde( rename = "sentry.item_id" ) ]
2484+ pub item_id : String ,
2485+ pub trace : Option < String > ,
2486+ pub severity : Option < String > ,
2487+ pub timestamp : String ,
2488+ pub message : Option < String > ,
2489+ }
0 commit comments