Turn an object according the normal of a selected face from second mesh
Made a couple of changes to this script, the main one is using the Vector.rotation_difference method instead of the angle method. This one calculates rotation in all 3 axes.

import bpy
import bmesh
from mathutils import Vector
from math import degrees # Added for more readable printing of rotation angles

class TestPanel(bpy.types.Panel):
    bl_idname = "object.test_panel"
    bl_label = "Test Panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'

    def draw(self, context):
        layout = self.layout
        layout.operator("object.clone_object", text="Add Suzanne")


class AddCloneObject(bpy.types.Operator):
    bl_idname = "object.clone_object"
    bl_label = "Clone object"

    def execute(self, context):

        if context.object.mode == 'EDIT':
           bpy.ops.object.mode_set(mode='OBJECT')
           obj = bpy.context.active_object

           bm = bmesh.new()
           bm.from_mesh(obj.data)

           selected_faces = [f for f in bm.faces if f.select]

           for face in selected_faces:

               face_location = face.calc_center_median() 
               loc_world_space = obj.matrix_world * Vector(face_location) 
               z = Vector((0,0,1))

               # Changes start here
               rot = z.rotation_difference( face.normal ).to_euler()
               bpy.context.scene.cursor_location = loc_world_space

               bpy.ops.mesh.primitive_monkey_add(radius=0.5) 

               bpy.context.object.rotatation_euler = rot

               print("face location = ", loc_world_space)
               print("rotation = ", [degrees(a) for a in rot] )
               print("Suzanne = ", context.active_object.matrix_world)
               # And End here

           bm.to_mesh(obj.data)
           bm.free()

           return {'FINISHED'}

       else:
           self.report({'INFO'}, "Need to be in edit_mode")

           return {'FINISHED'}

def register():
    bpy.utils.register_module(__name__)

def unregister():
    bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
    register()