Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import "go.uber.org/zap" fails #1172

Closed
mpl opened this issue Jul 6, 2021 · 17 comments · Fixed by #1516
Closed

import "go.uber.org/zap" fails #1172

mpl opened this issue Jul 6, 2021 · 17 comments · Fixed by #1516
Labels
area/core bug Something isn't working

Comments

@mpl
Copy link
Collaborator

mpl commented Jul 6, 2021

The following program sample.go triggers an unexpected result

package main

import (
	"time"

	"go.uber.org/zap"
)

func main() {
	logger, _ := zap.NewProduction()
	// defer logger.Sync() // flushes buffer, if any
	sugar := logger.Sugar()
	sugar.Infow("failed to fetch URL",
		// Structured context as loosely typed key-value pairs.
		"url", "blabla",
		"attempt", 3,
		"backoff", time.Second,
	)
	sugar.Infof("Failed to fetch URL: %s", "blabla")
}

Expected result

{"level":"info","ts":1625585709.656375,"caller":"yaegi/foo.go:15","msg":"failed to fetch URL","url":"blabla","attempt":3,"backoff":1}
{"level":"info","ts":1625585709.656471,"caller":"yaegi/foo.go:21","msg":"Failed to fetch URL: blabla"}

Got

% yaegi run -unrestricted -unsafe ./sample.go
run: ./foo.go:8:2: import "go.uber.org/zap" error: /Users/mpl/src/go.uber.org/zap/array.go:26:2: import "go.uber.org/zap/zapcore" error: /Users/mpl/src/go.uber.org/zap/zapcore/entry.go:31:2: import "go.uber.org/zap/internal/exit" error: /Users/mpl/src/go.uber.org/zap/internal/exit/exit.go:32:2: not enough arguments in call to real

Yaegi Version

devel

Additional Notes

Hints at: https://github.com/uber-go/zap/blob/master/internal/exit/exit.go#L27

@mpl
Copy link
Collaborator Author

mpl commented Jul 6, 2021

@darkweak fyi, I was able to get past your issue by changing all func() signatures to func(i int) , so that they would match the os.Exit signature. Not a real fix of course, but that allowed us to see that there's other problems waiting behind. So it's going to be several fixes before you can use that package in yaegi.

@darkweak
Copy link

darkweak commented Jul 6, 2021

So, what's next ? Is there another way to make plugins for træfik instead of using yaegi while you're trying to fix this bug ? @mpl

@ldez
Copy link
Member

ldez commented Jul 7, 2021

The plugin's system inside Traefik is based on Yaegi, then there is no other way.
You have to wait for the Yaegi fix or fork go.uber.org/zap to fix the problem with the real function.

@darkweak
Copy link

darkweak commented Jul 7, 2021

@ldez I don't think fork the zap project and patch by myself is a good and viable solution. When does the fix would be available ? As rc or concrete release idc, that's just for testing purpose and be able to prepare the release of this plugin.

@ldez
Copy link
Member

ldez commented Jul 7, 2021

you can follow #1173 and #1174

@mpl
Copy link
Collaborator Author

mpl commented Jul 8, 2021

@darkweak FYI, with #1174, #1176, #1178, and #1180 now merged , the example above goes much further, but we're now hitting problems in sync/pool, so there's more work (potentially trickier, yet to be determined) to be done.

@darkweak
Copy link

darkweak commented Jul 8, 2021

Thank you, and many thanks to @mvertes for his incredible work 🚀

@jptosso
Copy link

jptosso commented Sep 6, 2021

I want to add something to this issue (I'm using 4653d87):

scope.go:225: nil reflect type
panic: nil reflect type [recovered]
	panic: /Users/jptosso/go/src/github.com/jptosso/coraza-waf/vendor/go.uber.org/zap/logger.go:309:2: CFG post-order panic: nil reflect type

goroutine 1 [running]:
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2.1(0xc0015ed8c0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/cfg.go:467 +0xb7
panic(0x1a212c0, 0xc000f08b00)
	/usr/local/Cellar/go/1.16.5/libexec/src/runtime/panic.go:965 +0x1b9
log.Panic(0xc0009120b0, 0x1, 0x1)
	/usr/local/Cellar/go/1.16.5/libexec/src/log/log.go:354 +0xae
github.com/traefik/yaegi/interp.(*scope).add(0xc000fc01b0, 0xc0004962d0, 0x1)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/scope.go:225 +0x175
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2(0xc0015ed8c0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/cfg.go:1672 +0x2226
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015ed8c0, 0xc000912e10, 0xc000912dd8)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:288 +0xa6
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015ed7a0, 0xc000912e10, 0xc000912dd8)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015e17a0, 0xc000912e10, 0xc000912dd8)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015dfd40, 0xc000912e10, 0xc000912dd8)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*node).Walk(0xc0014e5560, 0xc000912e10, 0xc000912dd8)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*Interpreter).cfg(0xc00033e200, 0xc0014e5560, 0xc0000de2e9, 0xf, 0xc00056970d, 0x3, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/cfg.go:60 +0x2a7
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc00033e200, 0xc000042810, 0x24, 0xc0000de2e9, 0xf, 0xc000640c01, 0xc0000c2610, 0x5, 0x0, 0xf)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/src.go:117 +0x68f
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc00063d7a0, 0xc00054bb98)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/gta.go:226 +0x1390
github.com/traefik/yaegi/interp.(*node).Walk(0xc00063d7a0, 0xc000913b98, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:281 +0xb6
github.com/traefik/yaegi/interp.(*node).Walk(0xc00063d440, 0xc000913b98, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*node).Walk(0xc00063d200, 0xc000913b98, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc00033e200, 0xc00063d200, 0xc0000427e0, 0x2d, 0xc0000c42a1, 0x2d, 0xc00060f4c0, 0xf, 0xc00063d200, 0x0, ...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/gta.go:20 +0x258
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc00033e200, 0xc0001986c0, 0x1d, 0xc0000c42a1, 0x2d, 0xc000171301, 0xc00033e200, 0xc00054c078, 0xc00054c078, 0x6)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/src.go:100 +0xfe5
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc0005ff9e0, 0xc00054c948)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/gta.go:226 +0x1390
github.com/traefik/yaegi/interp.(*node).Walk(0xc0005ff9e0, 0xc000914948, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:281 +0xb6
github.com/traefik/yaegi/interp.(*node).Walk(0xc0005ff680, 0xc000914948, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*node).Walk(0xc0005ff440, 0xc000914948, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc00033e200, 0xc0005ff440, 0xc0001986c0, 0x1d, 0xc00050c041, 0x1d, 0xc000203f58, 0x6, 0xc0005ff440, 0x0, ...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/gta.go:20 +0x258
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc00033e200, 0xc000203d7a, 0x1, 0xc00050c041, 0x1d, 0xc00020c401, 0x0, 0x1, 0x2343f18, 0x6)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/src.go:100 +0xfe5
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc0003eb440, 0xc0001cf6f8)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/gta.go:226 +0x1390
github.com/traefik/yaegi/interp.(*node).Walk(0xc0003eb440, 0xc0009156f8, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:281 +0xb6
github.com/traefik/yaegi/interp.(*node).Walk(0xc0003eaa20, 0xc0009156f8, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*node).Walk(0xc0003ea7e0, 0xc0009156f8, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:285 +0x67
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc00033e200, 0xc0003ea7e0, 0xc000203d7a, 0x1, 0xc0002039ac, 0x2, 0xc000203a90, 0x6, 0xc0003ea7e0, 0x0, ...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/gta.go:20 +0x258
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc00033e200, 0x1cd9d58, 0x1, 0xc0002039ac, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/src.go:100 +0xfe5
github.com/traefik/yaegi/interp.(*Interpreter).EvalTest(...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/interp/interp.go:509
main.test(0xc0000ca000, 0x0, 0x0, 0xc000094101, 0xc00008a480)
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/cmd/yaegi/test.go:151 +0x106a
main.main()
	/Users/jptosso/go/pkg/mod/github.com/traefik/yaegi@v0.9.24-0.20210906162404-4653d8729892/cmd/yaegi/yaegi.go:135 +0x505

code:

ce.ErrorOutput = log.errorOutput

Should I create a new issue?

@mvertes
Copy link
Member

mvertes commented Sep 6, 2021

I'm seeing a couple of similar issues following the rework on types, under investigation right now. No need for a new issue, thanks.

mvertes added a commit that referenced this issue Sep 8, 2021
Make sure to keep always a single copy of incomplete type structures.
Remove remnants of recursive types processing.

Now `import "go.uber.org/zap"` works again (see #1172), fixing regressions
introduced by #1236.
traefiker pushed a commit that referenced this issue Sep 13, 2021
Make sure to keep always a single copy of incomplete type structures.
Remove remnants of recursive types processing.

Now `import "go.uber.org/zap"` works again (see #1172), fixing regressions
introduced by #1236.
traefiker pushed a commit that referenced this issue Sep 13, 2021
Make sure to keep always a single copy of incomplete type structures.
Remove remnants of recursive types processing.

Now `import "go.uber.org/zap"` works again (see #1172), fixing regressions
introduced since #1236.
@ldez ldez removed this from the v0.13.x milestone Aug 3, 2022
@ldez ldez modified the milestone: v0.14.x Aug 3, 2022
@taliesins
Copy link

I have copied the zap source code into my project (messed around with namespaces too) but I eventually got a minimal logging example to work. I had to use go 1.9 so that I could use the native sync/atomic package so that I could drop the uber atomic packaged which uses unsafe.

Quite a lot of the fixes relate to helping yeagi understand the type

Example 1

Broken:

func AddSync(w io.Writer) WriteSyncer {
	switch w := w.(type) {
	case WriteSyncer:
		return w
	default:
		return writerWrapper{w}
	}
}

To:

func AddSync(w io.Writer) WriteSyncer {
	switch w := w.(type) {
	case WriteSyncer:
		return w
	default:
		var wrapper WriteSyncer
		wrapper = writerWrapper{w}
		return wrapper
	}
}

Example 2
Broken

func (c *ioCore) Write(ent Entry, fields []Field) error {
	buf, err := c.enc.EncodeEntry(ent, fields)
	if err != nil {
		return err
	}
	_, err = c.out.Write(buf.Bytes())
	buf.Free()
	if err != nil {
		return err
	}
	if ent.Level > level.ErrorLevel {
		// Since we may be crashing the program, sync the output. Ignore Sync
		// errors, pending a clean solution to issue #370.
		c.Sync()
	}
	return nil
}

to

func (c *ioCore) Write(ent Entry, fields []Field) error {

	buf, err := c.enc.EncodeEntry(ent, fields)
	if err != nil {
		return err
	}
	if c.out != nil {
		var ioWriter io.Writer
		ioWriter = c.out
		_, err = ioWriter.Write(buf.Bytes())
	}
	buf.Free()
	if err != nil {
		return err
	}
	if ent.Level > level.ErrorLevel {
		// Since we may be crashing the program, sync the output. Ignore Sync
		// errors, pending a clean solution to issue #370.
		c.Sync()
	}
	return nil
}

func (c *ioCore) Sync() error {
	if c.out == nil {
		return nil
	}
	return c.out.Sync()
}

https://github.com/taliesins/traefik-plugin-oidc/tree/initial/log

@taliesins
Copy link

#1485 is required for zap to work

@mnsmithuk
Copy link

Any updates on this fix being merged. I think it is holding up the CorazaWAF traefik plugin from working which I would like to test and use with traefik.

@jptosso
Copy link

jptosso commented Dec 23, 2022

Any updates on this fix being merged. I think it is holding up the CorazaWAF traefik plugin from working which I would like to test and use with traefik.

Zap was removed from coraza v3. We have other problems with sync.Pool

@mnsmithuk
Copy link

Any updates on this fix being merged. I think it is holding up the CorazaWAF traefik plugin from working which I would like to test and use with traefik.

Zap was removed from coraza v3. We have other problems with sync.Pool

Ah ok. Thanks for a speedy response. Any estimate on when a fix for sync.Pool will be available?

@jptosso
Copy link

jptosso commented Dec 23, 2022

No idea, there is no ongoing project for Traefik until we find a maintainer. We try yaegi once in a while to check whether it works but no success yet.
Coraza is designed to work in wasm using tinygo so it is highly portable, but still it doesn't work.

@mnsmithuk
Copy link

No idea, there is no ongoing project for Traefik until we find a maintainer. We try yaegi once in a while to check whether it works but no success yet. Coraza is designed to work in wasm using tinygo so it is highly portable, but still it doesn't work.

Ok thanks. May have to look at testing by running a Caddy container in front of my traefik container as from the Coraza site it seems Caddy integration looks fully stable.

@jptosso
Copy link

jptosso commented Dec 23, 2022

No idea, there is no ongoing project for Traefik until we find a maintainer. We try yaegi once in a while to check whether it works but no success yet. Coraza is designed to work in wasm using tinygo so it is highly portable, but still it doesn't work.

Ok thanks. May have to look at testing by running a Caddy container in front of my traefik container as from the Coraza site it seems Caddy integration looks fully stable.

Other very popular integrations are apisix or envoy using coraza-proxy-wasm

traefiker pushed a commit that referenced this issue Mar 6, 2023
For methods defined on interfaces (vs concrete methods), the resolution of the method is necessarily delayed at the run time and can not be completed at compile time.

The selectorExpr processing has been changed to correctly identify calls on interface methods which were confused as fields rather than methods (due to the fact that in a interface definition, methods are fields of the interface).

Then at runtime, method lookup has been fixed to correctly recurse in nested valueInterface wrappers and to find embedded interface fields in case of struct or pointer to struct.

Finally, remove receiver processing in `call()`.The receiver is already processed at method resolution and in genFunctionWrapper. Removing redundant processing in call fixes handling of variadic method, simplifies the code and makes it faster.

With those fixes, it is now possible to load and run `go.uber.org/zap` in yaegi. In turn, it makes possible for yaegi to run plugins dependent on zap, such as coraza-waf.

Fixes #1515, 
Fixes #1172,
Fixes #1275,
Fixes #1485.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants