diff --git a/_examples/logging/request-logger/accesslog-template/main.go b/_examples/logging/request-logger/accesslog-template/main.go
index 66b02dd46a..5401a067e6 100644
--- a/_examples/logging/request-logger/accesslog-template/main.go
+++ b/_examples/logging/request-logger/accesslog-template/main.go
@@ -20,17 +20,14 @@ func main() {
 	ac.AddFields(func(ctx iris.Context, fields *accesslog.Fields) {
 		fields.Set("IP", ctx.RemoteAddr())
 	})
+
 	// 2. Use Template formatter's `Text` value
-	// to customize the look & feel of a log.
-	// You could also use its `Tmpl` field to
-	// set a *template.Template instance.
+	// to define a log line format.
 	ac.SetFormatter(&accesslog.Template{
 		Text: `{{.Now.Format .TimeFormat}} {{.Path}} {{.Code}} {{.Fields.Get "IP" }}
-`,
+`, /*             2020-09-10 21:38:13 / 200 ::1 */
 	})
-	// Example Output:
-	// 2020-09-10 21:38:13 / 200 ::1
-
+	// 3. Register the middleware. That's all.
 	app.UseRouter(ac.Handler)
 
 	app.Get("/", index)
@@ -41,3 +38,26 @@ func main() {
 func index(ctx iris.Context) {
 	ctx.WriteString("Index")
 }
+
+/* Use a custom *template.Template:
+
+// 2.1 The log line format:
+text := `{{.Now.Format .TimeFormat}} {{.Path}} {{.Code}} {{.Fields.Get "IP" }}
+`
+//
+// 2.2 Parse the template, optionally using custom Template Functions.
+tmpl := template.Must(template.New("").Funcs(template.FuncMap{
+	// Custom functions you may want to use inside "text",
+	// e.g. prefixFields .Fields "my_prefix"
+	// to get a slice of fields starts with "my_prefix"
+	// and later, in the template, loop through them and render their values.
+	// "key": func(input) string { return ... }
+}).Parse(text))
+//
+// 3. Use Template formatter's `Text` value
+// or the `Tmpl` field to customize the look & feel of a log.
+ac.SetFormatter(&accesslog.Template{
+	Tmpl: tmpl,
+})
+
+*/
diff --git a/middleware/accesslog/accesslog.go b/middleware/accesslog/accesslog.go
index a6e8036e9f..c0ada8854b 100644
--- a/middleware/accesslog/accesslog.go
+++ b/middleware/accesslog/accesslog.go
@@ -553,7 +553,7 @@ func (ac *AccessLog) Print(ctx *context.Context, latency time.Duration, timeForm
 		log.Logger = ac
 		log.Now = now
 		log.TimeFormat = timeFormat
-		log.Timestamp = now.Unix()
+		log.Timestamp = now.UnixNano() / 1000000
 		log.Latency = latency
 		log.Method = method
 		log.Path = path
diff --git a/middleware/accesslog/log.go b/middleware/accesslog/log.go
index 3f68f2ff03..bc9792ee74 100644
--- a/middleware/accesslog/log.go
+++ b/middleware/accesslog/log.go
@@ -23,7 +23,7 @@ type Log struct {
 	// TimeFormat selected to print the Time as string,
 	// useful on Template Formatter.
 	TimeFormat string `json:"-" yaml:"-" toml:"-"`
-	// Timestamp the Now's unix timestamp (seconds).
+	// Timestamp the Now's unix timestamp (milliseconds).
 	Timestamp int64 `json:"timestamp"`
 
 	// Request-Response latency.
@@ -192,10 +192,12 @@ type Template struct {
 	// Custom template source.
 	// Use this or `Tmpl/TmplName` fields.
 	Text string
-	// Custom template to use, overrides the `Text` field if not nil.
+	// Custom template funcs to used when `Text` is not empty.
+	Funcs template.FuncMap
+
+	// Custom template to use, overrides the `Text` and `Funcs` fields.
 	Tmpl *template.Template
-	// If not empty then this named template/block
-	// is response to hold the log result.
+	// If not empty then this named template/block renders the log line.
 	TmplName string
 
 	dest io.Writer
@@ -206,12 +208,16 @@ type Template struct {
 // when this formatter is registered.
 func (f *Template) SetOutput(dest io.Writer) {
 	if f.Tmpl == nil {
+		tmpl := template.New("")
+
 		text := f.Text
-		if f.Text == "" {
+		if text != "" {
+			tmpl.Funcs(f.Funcs)
+		} else {
 			text = defaultTmplText
 		}
 
-		f.Tmpl = template.Must(template.New("").Parse(text))
+		f.Tmpl = template.Must(tmpl.Parse(text))
 	}
 
 	f.dest = dest