2222import org .apache .lucene .index .DirectoryReader ;
2323import org .apache .lucene .index .FilterLeafReader ;
2424import org .apache .lucene .index .IndexCommit ;
25+ import org .apache .lucene .index .IndexFileNames ;
2526import org .apache .lucene .index .IndexReader ;
2627import org .apache .lucene .index .IndexWriter ;
2728import org .apache .lucene .index .LeafReader ;
2829import org .apache .lucene .index .LeafReaderContext ;
2930import org .apache .lucene .index .SegmentCommitInfo ;
31+ import org .apache .lucene .index .SegmentInfo ;
3032import org .apache .lucene .index .SegmentInfos ;
3133import org .apache .lucene .index .SegmentReader ;
3234import org .apache .lucene .index .SnapshotDeletionPolicy ;
3638import org .apache .lucene .search .SearcherManager ;
3739import org .apache .lucene .search .join .BitSetProducer ;
3840import org .apache .lucene .store .AlreadyClosedException ;
41+ import org .apache .lucene .store .Directory ;
42+ import org .apache .lucene .store .IOContext ;
3943import org .apache .lucene .util .Accountable ;
4044import org .apache .lucene .util .Accountables ;
4145import org .elasticsearch .ExceptionsHelper ;
4246import org .elasticsearch .common .Base64 ;
4347import org .elasticsearch .common .Nullable ;
4448import org .elasticsearch .common .bytes .BytesReference ;
49+ import org .elasticsearch .common .collect .ImmutableOpenMap ;
4550import org .elasticsearch .common .io .stream .StreamInput ;
4651import org .elasticsearch .common .io .stream .StreamOutput ;
4752import org .elasticsearch .common .io .stream .Writeable ;
6469import org .elasticsearch .index .translog .Translog ;
6570
6671import java .io .Closeable ;
72+ import java .io .FileNotFoundException ;
6773import java .io .IOException ;
74+ import java .nio .file .NoSuchFileException ;
6875import java .util .Arrays ;
76+ import java .util .Collection ;
6977import java .util .Comparator ;
7078import java .util .HashMap ;
7179import java .util .List ;
@@ -406,7 +414,7 @@ protected static SegmentInfos readLastCommittedSegmentInfos(final SearcherManage
406414 /**
407415 * Global stats on segments.
408416 */
409- public final SegmentsStats segmentsStats () {
417+ public final SegmentsStats segmentsStats (boolean includeSegmentFileSizes ) {
410418 ensureOpen ();
411419 try (final Searcher searcher = acquireSearcher ("segments_stats" )) {
412420 SegmentsStats stats = new SegmentsStats ();
@@ -418,12 +426,81 @@ public final SegmentsStats segmentsStats() {
418426 stats .addTermVectorsMemoryInBytes (guardedRamBytesUsed (segmentReader .getTermVectorsReader ()));
419427 stats .addNormsMemoryInBytes (guardedRamBytesUsed (segmentReader .getNormsReader ()));
420428 stats .addDocValuesMemoryInBytes (guardedRamBytesUsed (segmentReader .getDocValuesReader ()));
429+
430+ if (includeSegmentFileSizes ) {
431+ // TODO: consider moving this to StoreStats
432+ stats .addFileSizes (getSegmentFileSizes (segmentReader ));
433+ }
421434 }
422435 writerSegmentStats (stats );
423436 return stats ;
424437 }
425438 }
426439
440+ private ImmutableOpenMap <String , Long > getSegmentFileSizes (SegmentReader segmentReader ) {
441+ Directory directory = null ;
442+ SegmentCommitInfo segmentCommitInfo = segmentReader .getSegmentInfo ();
443+ boolean useCompoundFile = segmentCommitInfo .info .getUseCompoundFile ();
444+ if (useCompoundFile ) {
445+ try {
446+ directory = engineConfig .getCodec ().compoundFormat ().getCompoundReader (segmentReader .directory (), segmentCommitInfo .info , IOContext .READ );
447+ } catch (IOException e ) {
448+ logger .warn ("Error when opening compound reader for Directory [{}] and SegmentCommitInfo [{}]" , e ,
449+ segmentReader .directory (), segmentCommitInfo );
450+
451+ return ImmutableOpenMap .of ();
452+ }
453+ } else {
454+ directory = segmentReader .directory ();
455+ }
456+
457+ assert directory != null ;
458+
459+ String [] files ;
460+ if (useCompoundFile ) {
461+ try {
462+ files = directory .listAll ();
463+ } catch (IOException e ) {
464+ logger .warn ("Couldn't list Compound Reader Directory [{}]" , e , directory );
465+ return ImmutableOpenMap .of ();
466+ }
467+ } else {
468+ try {
469+ files = segmentReader .getSegmentInfo ().files ().toArray (new String []{});
470+ } catch (IOException e ) {
471+ logger .warn ("Couldn't list Directory from SegmentReader [{}] and SegmentInfo [{}]" , e , segmentReader , segmentReader .getSegmentInfo ());
472+ return ImmutableOpenMap .of ();
473+ }
474+ }
475+
476+ ImmutableOpenMap .Builder <String , Long > map = ImmutableOpenMap .builder ();
477+ for (String file : files ) {
478+ String extension = IndexFileNames .getExtension (file );
479+ long length = 0L ;
480+ try {
481+ length = directory .fileLength (file );
482+ } catch (NoSuchFileException | FileNotFoundException e ) {
483+ logger .warn ("Tried to query fileLength but file is gone [{}] [{}]" , e , directory , file );
484+ } catch (IOException e ) {
485+ logger .warn ("Error when trying to query fileLength [{}] [{}]" , e , directory , file );
486+ }
487+ if (length == 0L ) {
488+ continue ;
489+ }
490+ map .put (extension , length );
491+ }
492+
493+ if (useCompoundFile && directory != null ) {
494+ try {
495+ directory .close ();
496+ } catch (IOException e ) {
497+ logger .warn ("Error when closing compound reader on Directory [{}]" , e , directory );
498+ }
499+ }
500+
501+ return map .build ();
502+ }
503+
427504 protected void writerSegmentStats (SegmentsStats stats ) {
428505 // by default we don't have a writer here... subclasses can override this
429506 stats .addVersionMapMemoryInBytes (0 );
0 commit comments