@@ -63,6 +63,7 @@ interface AwsLogOptions {
6363 */
6464export class AwsEcsDetector implements ResourceDetector {
6565 static readonly CONTAINER_ID_LENGTH = 64 ;
66+ static readonly CONTAINER_ID_LENGTH_MIN = 32 ;
6667 static readonly DEFAULT_CGROUP_PATH = '/proc/self/cgroup' ;
6768
6869 private static readFileAsync = util . promisify ( fs . readFile ) ;
@@ -161,62 +162,71 @@ export class AwsEcsDetector implements ResourceDetector {
161162 AwsEcsDetector . DEFAULT_CGROUP_PATH ,
162163 'utf8'
163164 ) ;
164- const splitData = rawData . trim ( ) . split ( '\n' ) ;
165- for ( const str of splitData ) {
166- containerId = this . _extractContainerIdFromLine ( str ) ;
167- if ( containerId ) {
168- break ;
169- }
165+ const lines = rawData
166+ . split ( '\n' )
167+ . map ( s => s . trim ( ) )
168+ . filter ( Boolean ) ;
169+
170+ // Pass 1: Prefer primary ECS pattern across all lines
171+ for ( const line of lines ) {
172+ const id = this . _extractPrimaryEcsContainerId ( line ) ;
173+ if ( id ) return id ;
174+ }
175+
176+ // Pass 2: Fallback to last-segment with strict allowed chars (hex + hyphen)
177+ for ( const line of lines ) {
178+ const id = this . _extractLastSegmentContainerId ( line ) ;
179+ if ( id ) return id ;
180+ }
181+
182+ // Pass 3: Legacy fallback to last 64 chars (Docker-style), keep existing behavior
183+ for ( const line of lines ) {
184+ const id = this . _extractLegacyContainerId ( line ) ;
185+ if ( id ) return id ;
170186 }
171187 } catch ( e ) {
172188 diag . debug ( 'AwsEcsDetector failed to read container ID' , e ) ;
173189 }
174190 return containerId ;
175191 }
176192
177- /**
178- * Extract container ID from a cgroup line using regex pattern matching.
179- * Handles the new AWS ECS Fargate format: /ecs/<taskId>/<taskId>-<containerId>
180- * Returns the last segment after the final '/' which should be the complete container ID.
181- */
182- private _extractContainerIdFromLine ( line : string ) : string | undefined {
183- if ( ! line ) {
184- return undefined ;
185- }
186193
187- // Primary pattern: Match /ecs/taskId/taskId-containerId format (new ECS Fargate)
188- // This captures the full taskId-containerId part after the last slash
194+ // Prefer primary ECS format extraction
195+ private _extractPrimaryEcsContainerId ( line : string ) : string | undefined {
189196 const ecsPattern = / \/ e c s \/ [ a - f A - F 0 - 9 - ] + \/ ( [ a - f A - F 0 - 9 - ] + ) $ / ;
190- const ecsMatch = line . match ( ecsPattern ) ;
197+ const match = line . match ( ecsPattern ) ;
191198 if (
192- ecsMatch &&
193- ecsMatch [ 1 ] &&
194- ecsMatch [ 1 ] . length >= 12 &&
195- ecsMatch [ 1 ] . length <= AwsEcsDetector . CONTAINER_ID_LENGTH
199+ match &&
200+ match [ 1 ] &&
201+ match [ 1 ] . length >= AwsEcsDetector . CONTAINER_ID_LENGTH_MIN &&
202+ match [ 1 ] . length <= AwsEcsDetector . CONTAINER_ID_LENGTH
196203 ) {
197- return ecsMatch [ 1 ] ;
198- }
199-
200- // Fallback: Extract last segment after slash for any path-like format
201- const segments = line . split ( '/' ) ;
202- if ( segments . length > 1 ) {
203- const lastSegment = segments [ segments . length - 1 ] ;
204- if (
205- lastSegment &&
206- lastSegment . length >= 12 &&
207- lastSegment . length <= AwsEcsDetector . CONTAINER_ID_LENGTH
208- ) {
209- return lastSegment ;
210- }
204+ return match [ 1 ] ;
211205 }
206+ return undefined ;
207+ }
212208
213- // Legacy fallback: original logic for lines that are just the container ID (64 chars)
209+ // Fallback: accept last path segment if it looks like a container id (hex + '-')
210+ private _extractLastSegmentContainerId ( line : string ) : string | undefined {
211+ const parts = line . split ( '/' ) ;
212+ if ( parts . length <= 1 ) return undefined ;
213+ const last = parts [ parts . length - 1 ] ;
214214 if (
215- line . length > AwsEcsDetector . CONTAINER_ID_LENGTH
215+ last &&
216+ last . length >= AwsEcsDetector . CONTAINER_ID_LENGTH_MIN &&
217+ last . length <= AwsEcsDetector . CONTAINER_ID_LENGTH &&
218+ / ^ [ a - f A - F 0 - 9 - ] + $ / . test ( last )
216219 ) {
217- return line . substring ( line . length - AwsEcsDetector . CONTAINER_ID_LENGTH ) ;
220+ return last ;
218221 }
222+ return undefined ;
223+ }
219224
225+ // Legacy fallback: keep existing behavior to avoid breaking users/tests
226+ private _extractLegacyContainerId ( line : string ) : string | undefined {
227+ if ( line . length > AwsEcsDetector . CONTAINER_ID_LENGTH ) {
228+ return line . substring ( line . length - AwsEcsDetector . CONTAINER_ID_LENGTH ) ;
229+ }
220230 return undefined ;
221231 }
222232
0 commit comments