func (l *AuditLog) SearchEvents(fromUTC, toUTC time.Time, query string) ([]EventFields, error) {
	log.Infof("auditLog.SearchEvents(%v, %v, query=%v)", fromUTC, toUTC, query)
	queryVals, err := url.ParseQuery(query)
	if err != nil {
		return nil, trace.BadParameter("query", query)
	}
	// how many days of logs to search?
	days := int(toUTC.Sub(fromUTC).Hours() / 24)
	if days < 0 {
		return nil, trace.BadParameter("query", query)
	}

	// scan the log directory:
	df, err := os.Open(l.dataDir)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	defer df.Close()
	entries, err := df.Readdir(-1)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	filtered := make([]os.FileInfo, 0, days)
	for i := range entries {
		fi := entries[i]
		if fi.IsDir() || filepath.Ext(fi.Name()) != LogfileExt {
			continue
		}
		fd := fi.ModTime().UTC()
		if fd.After(fromUTC) && fd.Before(toUTC) {
			filtered = append(filtered, fi)
		}
	}
	// sort all accepted  files by date
	sort.Sort(byDate(filtered))

	// search within each file:
	events := make([]EventFields, 0)
	for i := range filtered {
		found, err := l.findInFile(filepath.Join(l.dataDir, filtered[i].Name()), queryVals)
		if err != nil {
			return nil, trace.Wrap(err)
		}
		events = append(events, found...)
	}
	return events, nil
}
// Search finds events. Results show up sorted by date (newest first)
Search finds events. Results show up sorted by date (newest first)
// Search finds events . Results show up sorted by date ( newest first )
func (l *AuditLog) SearchEvents(fromUTC, toUTC time.Time, query string) ([]EventFields, error) {
	log.Infof("auditLog.SearchEvents(%v, %v, query=%v)", fromUTC, toUTC, query)
	queryVals, err := url.ParseQuery(query)
	if err != nil {
		return nil, trace.BadParameter("query", query)
	}
	days := int(toUTC.Sub(fromUTC).Hours() / 24)
	if days < 0 {
		return nil, trace.BadParameter("query", query)
	}
	df, err := os.Open(l.dataDir)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	defer df.Close()
	entries, err := df.Readdir(-1)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	filtered := make([]os.FileInfo, 0, days)
	for i := range entries {
		fi := entries[i]
		if fi.IsDir() || filepath.Ext(fi.Name()) != LogfileExt {
			continue
		}
		fd := fi.ModTime().UTC()
		if fd.After(fromUTC) && fd.Before(toUTC) {
			filtered = append(filtered, fi)
		}
	}
	sort.Sort(byDate(filtered))
	events := make([]EventFields, 0)
	for i := range filtered {
		found, err := l.findInFile(filepath.Join(l.dataDir, filtered[i].Name()), queryVals)
		if err != nil {
			return nil, trace.Wrap(err)
		}
		events = append(events, found...)
	}
	return events, nil
}
func ( l * AuditLog ) SearchEvents ( fromUTC , toUTC time . Time , query string ) ( [ ] EventFields , error ) { log . Infof ( " " , fromUTC , toUTC , query ) queryVals , err := url . ParseQuery ( query ) if err != nil { return nil , trace . BadParameter ( " " , query ) } days := int ( toUTC . Sub ( fromUTC ) . Hours ( ) / 24 ) if days < 0 { return nil , trace . BadParameter ( " " , query ) } df , err := os . Open ( l . dataDir ) if err != nil { return nil , trace . Wrap ( err ) } defer df . Close ( ) entries , err := df . Readdir ( - 1 ) if err != nil { return nil , trace . Wrap ( err ) } filtered := make ( [ ] os . FileInfo , 0 , days ) for i := range entries { fi := entries [ i ] if fi . IsDir ( ) || filepath . Ext ( fi . Name ( ) ) != LogfileExt { continue } fd := fi . ModTime ( ) . UTC ( ) if fd . After ( fromUTC ) && fd . Before ( toUTC ) { filtered = append ( filtered , fi ) } } sort . Sort ( byDate ( filtered ) ) events := make ( [ ] EventFields , 0 ) for i := range filtered { found , err := l . findInFile ( filepath . Join ( l . dataDir , filtered [ i ] . Name ( ) ) , queryVals ) if err != nil { return nil , trace . Wrap ( err ) } events = append ( events , found ... ) } return events , nil }
Search finds events.
Search finds events .
// how many days of logs to search? // scan the log directory: // sort all accepted  files by date // search within each file: