func saveMaxTime(tablename string, starttime time.Time, maxtime time.Time, duration int) {
	var timetosave time.Time
	if (starttime.Add(time.Hour * time.Duration(duration))).After(time.Now()) {
		timetosave = maxtime
	} else {
		timetosave = starttime.Add(time.Hour * time.Duration(duration))
	}
	registry.Save(config,
		tablename,
		timetosave.Format(time.RFC3339))
}
Save max time
package main
import (
	"flag"
	"fmt"
	"math"
	"os"
	"os/signal"
	"reflect"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"
	cfg "github.com/zensqlmonitor/influxdb-zabbix/config"
	helpers "github.com/zensqlmonitor/influxdb-zabbix/helpers"
	input "github.com/zensqlmonitor/influxdb-zabbix/input"
	log "github.com/zensqlmonitor/influxdb-zabbix/log"
	influx "github.com/zensqlmonitor/influxdb-zabbix/output/influxdb"
	registry "github.com/zensqlmonitor/influxdb-zabbix/reg"
)
var m runtime.MemStats
var exitChan = make(chan int)
var wg sync.WaitGroup
type TOMLConfig cfg.TOMLConfig
var config cfg.TOMLConfig
type DynMap map[string]interface{}
type Param struct {
	input  Input
	output Output
}
type Input struct {
	provider      string
	address       string
	tablename     string
	interval      int
	hoursperbatch int
}
type Output struct {
	address            string
	database           string
	username           string
	password           string
	precision          string
	outputrowsperbatch int
}
type InfluxDB struct {
	output Output
}
var mapTables = make(registry.MapTable)
func (p *Param) gatherData() error {
	var infoLogs []string
	var currTable string = p.input.tablename
	var currTableForLog string = helpers.RightPad(currTable, " ", 12-len(currTable))
	if err := registry.Read(&config, &mapTables); err != nil {
		fmt.Println(err)
		return err
	}
	starttimereg := registry.GetValueFromKey(mapTables, currTable)
	startimerfc, err := time.Parse("2006-01-02T15:04:05", starttimereg)
	if err != nil {
		startimerfc, err = time.Parse(time.RFC3339, starttimereg)
		if err != nil {
			return err
		}
	}
	var starttimestr string = strconv.FormatInt(startimerfc.Unix(), 10)
	var endtimetmp time.Time = startimerfc.Add(time.Hour * time.Duration(p.input.hoursperbatch))
	var endtimestr string = strconv.FormatInt(endtimetmp.Unix(), 10)
	var tlen int = len(currTable)
	infoLogs = append(infoLogs,
		fmt.Sprintf(
			"----------- | %s | [%v --> %v[",
			currTableForLog,
			startimerfc.Format("2006-01-02 15:04:00"),
			endtimetmp.Format("2006-01-02 15:04:00")))
	startwatch := time.Now()
	ext := input.NewExtracter(
		p.input.provider,
		p.input.address,
		currTable,
		starttimestr,
		endtimestr)
	if err := ext.Extract(); err != nil {
		log.Error(1, "Error while executing script: %s", err)
		return err
	}
	var rowcount int = len(ext.Result)
	infoLogs = append(infoLogs,
		fmt.Sprintf(
			"<-- Extract | %s | %v rows in %s",
			currTableForLog,
			rowcount,
			time.Since(startwatch)))
	var maxclock time.Time = startimerfc
	if ext.Maxclock.IsZero() == false {
		maxclock = ext.Maxclock
	}
	if rowcount == 0 {
		infoLogs = append(infoLogs,
			fmt.Sprintf(
				"--> Load    | %s | No data",
				currTableForLog))
	} else {
		startwatch = time.Now()
		inlineData := ""
		if rowcount <= p.output.outputrowsperbatch {
			inlineData = strings.Join(ext.Result[:], "\n")
			loa := influx.NewLoader(
				fmt.Sprintf(
					"%s/write?db=%s&precision=%s",
					p.output.address,
					p.output.database,
					p.output.precision),
				p.output.username,
				p.output.password,
				inlineData)
			if err := loa.Load(); err != nil {
				log.Error(1, "Error while loading data for %s. %s", currTable, err)
				return err
			}
			infoLogs = append(infoLogs,
				fmt.Sprintf(
					"--> Load    | %s | %v rows in %s",
					currTableForLog,
					rowcount,
					time.Since(startwatch)))
		} else {  
			var batches float64 = float64(rowcount) / float64(p.output.outputrowsperbatch)
			var batchesCeiled float64 = math.Ceil(batches)
			var batchLoops int = 1
			var minRange int = 0
			var maxRange int = 0
			for batches > 0 {  
				if batchLoops == 1 {
					minRange = 0
				} else {
					minRange = maxRange
				}
				maxRange = batchLoops * p.output.outputrowsperbatch
				if maxRange >= rowcount {
					maxRange = rowcount
				}
				datapart := []string{}
				for i := minRange; i < maxRange; i++ {
					datapart = append(datapart, ext.Result[i])
				}
				inlineData = strings.Join(datapart[:], "\n")
				startwatch = time.Now()
				loa := influx.NewLoader(
					fmt.Sprintf(
						"%s/write?db=%s&precision=%s",
						p.output.address,
						p.output.database,
						p.output.precision),
					p.output.username,
					p.output.password,
					inlineData)
				if err := loa.Load(); err != nil {
					log.Error(1, "Error while loading data for %s. %s", currTable, err)
					return err
				}
				tableBatchName := fmt.Sprintf("%s (%v/%v)",
					currTable,
					batchLoops,
					batchesCeiled)
				tlen = len(tableBatchName)
				infoLogs = append(infoLogs,
					fmt.Sprintf("--> Load    | %s | %v rows in %s",
						helpers.RightPad(tableBatchName, " ", 13-tlen),
						len(datapart),
						time.Since(startwatch)))
				batchLoops += 1
				batches -= 1
			}  
		}
	}
	saveMaxTime(currTable, startimerfc, maxclock, p.input.hoursperbatch)
	tlen = len(currTable)
	infoLogs = append(infoLogs,
		fmt.Sprintf("--- Waiting | %s | %v sec ",
			currTableForLog,
			p.input.interval))
	if config.Logging.LevelFile == "Trace" || config.Logging.LevelConsole == "Trace" {
		runtime.ReadMemStats(&m)
		log.Trace(fmt.Sprintf("--- Memory usage: Alloc = %s | TotalAlloc = %s | Sys = %s | NumGC = %v", 
			helpers.IBytes(m.Alloc / 1024), 
			helpers.IBytes(m.TotalAlloc / 1024), 
			helpers.IBytes(m.Sys / 1024), 
			m.NumGC))
	}
	print(infoLogs)
	return nil
}
func print(infoLogs []string) {
	for i := 0; i < len(infoLogs); i++ {
		log.Info(infoLogs[i])
	}
}