func (d *Dispatcher) CollectDiagnosticLogs() { defer trace.End(trace.Begin("")) m := diagnostic.NewDiagnosticManager(d.session) for k, l := range diagnosticLogs { if l == nil || !l.collect { continue } log.Infof("Collecting %s %s", k, l.name) var lines []string start := l.start for i := 0; i < 2; i++ { h, err := m.BrowseLog(d.ctx, l.host, l.key, start, 0) if err != nil { log.Errorf("Failed to collect %s %s: %s", k, l.name, err) break } lines = h.LineText if len(lines) != 0 { break // l.start was still valid, log was not rolled over } // log rolled over, start at the beginning. // TODO: If this actually happens we will have missed some log data, // it is possible to get data from the previous log too. start = 0 log.Infof("%s %s rolled over", k, l.name) } if len(lines) == 0 { log.Warnf("No log data for %s %s", k, l.name) continue } f, err := os.Create(l.name) if err != nil { log.Errorf("Failed to create local %s: %s", l.name, err) continue } defer f.Close() for _, line := range lines { fmt.Fprintln(f, line) } } }
// Get the current log header LineEnd of the hostd/vpxd logs. // With this we avoid collecting log file data that existed prior to install. func (d *Dispatcher) InitDiagnosticLogs(conf *config.VirtualContainerHostConfigSpec) { defer trace.End(trace.Begin("")) if d.isVC { diagnosticLogs[d.session.ServiceContent.About.InstanceUuid] = &diagnosticLog{"vpxd:vpxd.log", "vpxd.log", 0, nil, true} } var err error if d.session.Datastore == nil { if d.session.Datastore, err = d.session.Finder.DatastoreOrDefault(d.ctx, conf.ImageStores[0].Host); err != nil { log.Errorf("Failure finding image store from VCH config (%s): %s", conf.ImageStores[0].Host, err.Error()) return } log.Debugf("Found ds: %s", conf.ImageStores[0].Host) } // find the host(s) attached to given storage if d.session.Cluster == nil { if len(conf.ComputeResources) > 0 { rp := compute.NewResourcePool(d.ctx, d.session, conf.ComputeResources[0]) if d.session.Cluster, err = rp.GetCluster(d.ctx); err != nil { log.Errorf("Unable to get cluster for given resource pool %s: %s", conf.ComputeResources[0], err) return } } else { log.Errorf("Compute resource is empty") return } } hosts, err := d.session.Datastore.AttachedClusterHosts(d.ctx, d.session.Cluster) if err != nil { log.Errorf("Unable to get the list of hosts attached to given storage: %s", err) return } if d.session.Host == nil { // vCenter w/ auto DRS. // Set collect=false here as we do not want to collect all hosts logs, // just the hostd log where the VM is placed. for _, host := range hosts { diagnosticLogs[host.Reference().Value] = &diagnosticLog{"hostd", "hostd.log", 0, host, false} } } else { // vCenter w/ manual DRS or standalone ESXi var host *object.HostSystem if d.isVC { host = d.session.Host } diagnosticLogs[d.session.Host.Reference().Value] = &diagnosticLog{"hostd", "hostd.log", 0, host, true} } m := diagnostic.NewDiagnosticManager(d.session) for k, l := range diagnosticLogs { // get LineEnd without any LineText h, err := m.BrowseLog(d.ctx, l.host, l.key, math.MaxInt32, 0) if err != nil { log.Warnf("Disabling %s %s collection (%s)", k, l.name, err) diagnosticLogs[k] = nil continue } l.start = h.LineEnd } }